aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/video/exynos_hdmi.txt7
-rw-r--r--Documentation/devicetree/bindings/video/exynos_hdmiddc.txt7
-rw-r--r--Documentation/devicetree/bindings/video/exynos_hdmiphy.txt7
-rw-r--r--Documentation/devicetree/bindings/video/exynos_mixer.txt9
-rw-r--r--arch/arm/boot/dts/cros5250-common.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos5250-smdk5250.dts4
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi4
-rw-r--r--drivers/gpu/drm/drm_gem.c8
-rw-r--r--drivers/gpu/drm/drm_mm.c45
-rw-r--r--drivers/gpu/drm/drm_prime.c7
-rw-r--r--drivers/gpu/drm/exynos/exynos_ddc.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c7
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.c51
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c38
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c20
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c28
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c129
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c146
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.c102
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c63
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.c202
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c16
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_rotator.c53
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c50
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c131
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmiphy.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c122
-rw-r--r--drivers/gpu/drm/exynos/regs-mixer.h7
-rw-r--r--drivers/gpu/drm/nouveau/Makefile18
-rw-r--r--drivers/gpu/drm/nouveau/core/core/mm.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c27
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c93
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nva3.c21
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nve0.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv50.c36
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nvc0.c16
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nve0.c11
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nve0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/falcon.c (renamed from drivers/gpu/drm/nouveau/core/core/falcon.c)3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c53
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c601
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c401
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc)73
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc369
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc444
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h116
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc427
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h80
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc755
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc790
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h1020
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc770
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h959
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc53
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc400
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv50.c18
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c593
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h6
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nve0.c384
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/vp/nv84.c27
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/vp/nv98.c93
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/vp/nve0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/xtensa.c170
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h5
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/mm.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/bsp.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/copy.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/falcon.h (renamed from drivers/gpu/drm/nouveau/core/include/core/falcon.h)0
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/mpeg.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/vp.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/xtensa.h38
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/devinit.h21
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h95
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/vm.h5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c13
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/base.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c274
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c37
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c36
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pll.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c18
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/base.c23
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c329
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c78
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c87
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c90
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h25
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/base.c125
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c54
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c20
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c32
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c26
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c25
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c23
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c22
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c25
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c15
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c199
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c143
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/priv.h87
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c95
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c61
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c71
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c63
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c65
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c64
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c62
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c64
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c55
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c232
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c186
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/base.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c56
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c57
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c9
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c13
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c73
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c41
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c15
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c18
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c4
-rw-r--r--drivers/gpu/drm/nouveau/nva3_pm.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_pm.c8
-rw-r--r--drivers/gpu/drm/radeon/btc_dpm.c3
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c2
-rw-r--r--drivers/gpu/drm/radeon/ni_dpm.c26
-rw-r--r--drivers/gpu/drm/radeon/nid.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c40
-rw-r--r--drivers/gpu/drm/radeon/rv6xx_dpm.c26
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.c31
-rw-r--r--drivers/gpu/drm/radeon/rv770d.h4
-rw-r--r--drivers/gpu/drm/radeon/si_dpm.c20
-rw-r--r--drivers/gpu/drm/radeon/sid.h4
-rw-r--r--drivers/gpu/drm/radeon/sumo_dpm.c69
-rw-r--r--drivers/gpu/drm/radeon/trinity_dpm.c30
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_manager.c8
-rw-r--r--include/drm/drm_mm.h6
192 files changed, 7784 insertions, 6377 deletions
diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
index 589edee37394..c71d0f0b750a 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
@@ -1,7 +1,10 @@
Device-Tree bindings for drm hdmi driver
Required properties:
-- compatible: value should be "samsung,exynos5-hdmi".
+- compatible: value should be one among the following:
+ 1) "samsung,exynos5-hdmi" <DEPRECATED>
+ 2) "samsung,exynos4210-hdmi"
+ 3) "samsung,exynos4212-hdmi"
- reg: physical base address of the hdmi and length of memory mapped
region.
- interrupts: interrupt number to the cpu.
@@ -15,7 +18,7 @@ Required properties:
Example:
hdmi {
- compatible = "samsung,exynos5-hdmi";
+ compatible = "samsung,exynos4212-hdmi";
reg = <0x14530000 0x100000>;
interrupts = <0 95 0>;
hpd-gpio = <&gpx3 7 0xf 1 3>;
diff --git a/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt b/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt
index fa166d945809..41eee971562b 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt
@@ -1,12 +1,15 @@
Device-Tree bindings for hdmiddc driver
Required properties:
-- compatible: value should be "samsung,exynos5-hdmiddc".
+- compatible: value should be one of the following
+ 1) "samsung,exynos5-hdmiddc" <DEPRECATED>
+ 2) "samsung,exynos4210-hdmiddc"
+
- reg: I2C address of the hdmiddc device.
Example:
hdmiddc {
- compatible = "samsung,exynos5-hdmiddc";
+ compatible = "samsung,exynos4210-hdmiddc";
reg = <0x50>;
};
diff --git a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
index 858f4f9b902f..162f641f7639 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
@@ -1,12 +1,15 @@
Device-Tree bindings for hdmiphy driver
Required properties:
-- compatible: value should be "samsung,exynos5-hdmiphy".
+- compatible: value should be one of the following:
+ 1) "samsung,exynos5-hdmiphy" <DEPRECATED>
+ 2) "samsung,exynos4210-hdmiphy".
+ 3) "samsung,exynos4212-hdmiphy".
- reg: I2C address of the hdmiphy device.
Example:
hdmiphy {
- compatible = "samsung,exynos5-hdmiphy";
+ compatible = "samsung,exynos4210-hdmiphy";
reg = <0x38>;
};
diff --git a/Documentation/devicetree/bindings/video/exynos_mixer.txt b/Documentation/devicetree/bindings/video/exynos_mixer.txt
index 9b2ea0343566..3334b0a8e343 100644
--- a/Documentation/devicetree/bindings/video/exynos_mixer.txt
+++ b/Documentation/devicetree/bindings/video/exynos_mixer.txt
@@ -1,7 +1,12 @@
Device-Tree bindings for mixer driver
Required properties:
-- compatible: value should be "samsung,exynos5-mixer".
+- compatible: value should be one of the following:
+ 1) "samsung,exynos5-mixer" <DEPRECATED>
+ 2) "samsung,exynos4210-mixer"
+ 3) "samsung,exynos5250-mixer"
+ 4) "samsung,exynos5420-mixer"
+
- reg: physical base address of the mixer and length of memory mapped
region.
- interrupts: interrupt number to the cpu.
@@ -9,7 +14,7 @@ Required properties:
Example:
mixer {
- compatible = "samsung,exynos5-mixer";
+ compatible = "samsung,exynos5250-mixer";
reg = <0x14450000 0x10000>;
interrupts = <0 94 0>;
};
diff --git a/arch/arm/boot/dts/cros5250-common.dtsi b/arch/arm/boot/dts/cros5250-common.dtsi
index 3f0239ec1bc5..dc259e8b8a73 100644
--- a/arch/arm/boot/dts/cros5250-common.dtsi
+++ b/arch/arm/boot/dts/cros5250-common.dtsi
@@ -190,7 +190,7 @@
samsung,i2c-max-bus-freq = <66000>;
hdmiddc@50 {
- compatible = "samsung,exynos5-hdmiddc";
+ compatible = "samsung,exynos4210-hdmiddc";
reg = <0x50>;
};
};
@@ -224,7 +224,7 @@
samsung,i2c-max-bus-freq = <378000>;
hdmiphy@38 {
- compatible = "samsung,exynos5-hdmiphy";
+ compatible = "samsung,exynos4212-hdmiphy";
reg = <0x38>;
};
};
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 3e0c792e2767..f320d7cb4174 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -72,7 +72,7 @@
samsung,i2c-max-bus-freq = <66000>;
hdmiddc@50 {
- compatible = "samsung,exynos5-hdmiddc";
+ compatible = "samsung,exynos4210-hdmiddc";
reg = <0x50>;
};
};
@@ -102,7 +102,7 @@
samsung,i2c-max-bus-freq = <66000>;
hdmiphy@38 {
- compatible = "samsung,exynos5-hdmiphy";
+ compatible = "samsung,exynos4212-hdmiphy";
reg = <0x38>;
};
};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index fc9fb3d526e2..8b815c945949 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -601,7 +601,7 @@
};
hdmi {
- compatible = "samsung,exynos5-hdmi";
+ compatible = "samsung,exynos4212-hdmi";
reg = <0x14530000 0x70000>;
interrupts = <0 95 0>;
clocks = <&clock 333>, <&clock 136>, <&clock 137>,
@@ -611,7 +611,7 @@
};
mixer {
- compatible = "samsung,exynos5-mixer";
+ compatible = "samsung,exynos5250-mixer";
reg = <0x14450000 0x10000>;
interrupts = <0 94 0>;
};
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index bcedaf7b73b9..603f256152ef 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -108,12 +108,8 @@ drm_gem_init(struct drm_device *dev)
return -ENOMEM;
}
- if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
- DRM_FILE_PAGE_OFFSET_SIZE)) {
- drm_ht_remove(&mm->offset_hash);
- kfree(mm);
- return -ENOMEM;
- }
+ drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
+ DRM_FILE_PAGE_OFFSET_SIZE);
return 0;
}
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 07cf99cc8862..543b9b3171d3 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -669,7 +669,7 @@ int drm_mm_clean(struct drm_mm * mm)
}
EXPORT_SYMBOL(drm_mm_clean);
-int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
+void drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
{
INIT_LIST_HEAD(&mm->hole_stack);
INIT_LIST_HEAD(&mm->unused_nodes);
@@ -690,8 +690,6 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack);
mm->color_adjust = NULL;
-
- return 0;
}
EXPORT_SYMBOL(drm_mm_init);
@@ -699,8 +697,8 @@ void drm_mm_takedown(struct drm_mm * mm)
{
struct drm_mm_node *entry, *next;
- if (!list_empty(&mm->head_node.node_list)) {
- DRM_ERROR("Memory manager not clean. Delaying takedown\n");
+ if (WARN(!list_empty(&mm->head_node.node_list),
+ "Memory manager not clean. Delaying takedown\n")) {
return;
}
@@ -716,36 +714,37 @@ void drm_mm_takedown(struct drm_mm * mm)
}
EXPORT_SYMBOL(drm_mm_takedown);
-void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
+static unsigned long drm_mm_debug_hole(struct drm_mm_node *entry,
+ const char *prefix)
{
- struct drm_mm_node *entry;
- unsigned long total_used = 0, total_free = 0, total = 0;
unsigned long hole_start, hole_end, hole_size;
- hole_start = drm_mm_hole_node_start(&mm->head_node);
- hole_end = drm_mm_hole_node_end(&mm->head_node);
- hole_size = hole_end - hole_start;
- if (hole_size)
+ if (entry->hole_follows) {
+ hole_start = drm_mm_hole_node_start(entry);
+ hole_end = drm_mm_hole_node_end(entry);
+ hole_size = hole_end - hole_start;
printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n",
prefix, hole_start, hole_end,
hole_size);
- total_free += hole_size;
+ return hole_size;
+ }
+
+ return 0;
+}
+
+void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
+{
+ struct drm_mm_node *entry;
+ unsigned long total_used = 0, total_free = 0, total = 0;
+
+ total_free += drm_mm_debug_hole(&mm->head_node, prefix);
drm_mm_for_each_node(entry, mm) {
printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: used\n",
prefix, entry->start, entry->start + entry->size,
entry->size);
total_used += entry->size;
-
- if (entry->hole_follows) {
- hole_start = drm_mm_hole_node_start(entry);
- hole_end = drm_mm_hole_node_end(entry);
- hole_size = hole_end - hole_start;
- printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n",
- prefix, hole_start, hole_end,
- hole_size);
- total_free += hole_size;
- }
+ total_free += drm_mm_debug_hole(entry, prefix);
}
total = total_free + total_used;
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 52709f2171fb..1e0de41f085c 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -347,10 +347,13 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
out_have_obj:
get_dma_buf(dmabuf);
ret = dma_buf_fd(dmabuf, flags);
- if (ret < 0)
+ if (ret < 0) {
dma_buf_put(dmabuf);
- else
+ } else {
*prime_fd = ret;
+ ret = 0;
+ }
+
goto out;
fail_rm_handle:
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
index 4e9b5ba8edff..95c75edef01a 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -53,6 +53,8 @@ static struct of_device_id hdmiddc_match_types[] = {
{
.compatible = "samsung,exynos5-hdmiddc",
}, {
+ .compatible = "samsung,exynos4210-hdmiddc",
+ }, {
/* end node */
}
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 57affae9568b..22865baa03b1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -24,8 +24,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
enum dma_attr attr;
unsigned int nr_pages;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (buf->dma_addr) {
DRM_DEBUG_KMS("already allocated.\n");
return 0;
@@ -119,8 +117,6 @@ err_free_attrs:
static void lowlevel_buffer_deallocate(struct drm_device *dev,
unsigned int flags, struct exynos_drm_gem_buf *buf)
{
- DRM_DEBUG_KMS("%s.\n", __FILE__);
-
if (!buf->dma_addr) {
DRM_DEBUG_KMS("dma_addr is invalid.\n");
return;
@@ -151,7 +147,6 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
{
struct exynos_drm_gem_buf *buffer;
- DRM_DEBUG_KMS("%s.\n", __FILE__);
DRM_DEBUG_KMS("desired size = 0x%x\n", size);
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
@@ -167,8 +162,6 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
void exynos_drm_fini_buf(struct drm_device *dev,
struct exynos_drm_gem_buf *buffer)
{
- DRM_DEBUG_KMS("%s.\n", __FILE__);
-
if (!buffer) {
DRM_DEBUG_KMS("buffer is null.\n");
return;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 8bcc13ac9f73..02a8bc5226ca 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -34,7 +34,6 @@ convert_to_display_mode(struct drm_display_mode *mode,
struct exynos_drm_panel_info *panel)
{
struct fb_videomode *timing = &panel->timing;
- DRM_DEBUG_KMS("%s\n", __FILE__);
mode->clock = timing->pixclock / 1000;
mode->vrefresh = timing->refresh;
@@ -58,37 +57,6 @@ convert_to_display_mode(struct drm_display_mode *mode,
mode->flags |= DRM_MODE_FLAG_DBLSCAN;
}
-/* convert drm_display_mode to exynos_video_timings */
-static inline void
-convert_to_video_timing(struct fb_videomode *timing,
- struct drm_display_mode *mode)
-{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
- memset(timing, 0, sizeof(*timing));
-
- timing->pixclock = mode->clock * 1000;
- timing->refresh = drm_mode_vrefresh(mode);
-
- timing->xres = mode->hdisplay;
- timing->right_margin = mode->hsync_start - mode->hdisplay;
- timing->hsync_len = mode->hsync_end - mode->hsync_start;
- timing->left_margin = mode->htotal - mode->hsync_end;
-
- timing->yres = mode->vdisplay;
- timing->lower_margin = mode->vsync_start - mode->vdisplay;
- timing->vsync_len = mode->vsync_end - mode->vsync_start;
- timing->upper_margin = mode->vtotal - mode->vsync_end;
-
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- timing->vmode = FB_VMODE_INTERLACED;
- else
- timing->vmode = FB_VMODE_NONINTERLACED;
-
- if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
- timing->vmode |= FB_VMODE_DOUBLE;
-}
-
static int exynos_drm_connector_get_modes(struct drm_connector *connector)
{
struct exynos_drm_connector *exynos_connector =
@@ -99,8 +67,6 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
unsigned int count = 0;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (!display_ops) {
DRM_DEBUG_KMS("display_ops is null.\n");
return 0;
@@ -168,15 +134,12 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
to_exynos_connector(connector);
struct exynos_drm_manager *manager = exynos_connector->manager;
struct exynos_drm_display_ops *display_ops = manager->display_ops;
- struct fb_videomode timing;
int ret = MODE_BAD;
DRM_DEBUG_KMS("%s\n", __FILE__);
- convert_to_video_timing(&timing, mode);
-
- if (display_ops && display_ops->check_timing)
- if (!display_ops->check_timing(manager->dev, (void *)&timing))
+ if (display_ops && display_ops->check_mode)
+ if (!display_ops->check_mode(manager->dev, mode))
ret = MODE_OK;
return ret;
@@ -190,8 +153,6 @@ struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
struct drm_mode_object *obj;
struct drm_encoder *encoder;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
obj = drm_mode_object_find(dev, exynos_connector->encoder_id,
DRM_MODE_OBJECT_ENCODER);
if (!obj) {
@@ -234,8 +195,6 @@ void exynos_drm_display_power(struct drm_connector *connector, int mode)
static void exynos_drm_connector_dpms(struct drm_connector *connector,
int mode)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* in case that drm_crtc_helper_set_mode() is called,
* encoder/crtc->funcs->dpms() will be just returned
@@ -282,8 +241,6 @@ exynos_drm_connector_detect(struct drm_connector *connector, bool force)
manager->display_ops;
enum drm_connector_status status = connector_status_disconnected;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (display_ops && display_ops->is_connected) {
if (display_ops->is_connected(manager->dev))
status = connector_status_connected;
@@ -299,8 +256,6 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(exynos_connector);
@@ -322,8 +277,6 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
int type;
int err;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL);
if (!exynos_connector) {
DRM_ERROR("failed to allocate connector\n");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 4667c9f67acd..1bef6dc77478 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -27,8 +27,6 @@ static int exynos_drm_create_enc_conn(struct drm_device *dev,
struct drm_connector *connector;
int ret;
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
subdrv->manager->dev = subdrv->dev;
/* create and initialize a encoder for this sub driver. */
@@ -102,8 +100,6 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
static void exynos_drm_subdrv_remove(struct drm_device *dev,
struct exynos_drm_subdrv *subdrv)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
if (subdrv->remove)
subdrv->remove(dev, subdrv->dev);
}
@@ -114,8 +110,6 @@ int exynos_drm_device_register(struct drm_device *dev)
unsigned int fine_cnt = 0;
int err;
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
if (!dev)
return -EINVAL;
@@ -158,8 +152,6 @@ int exynos_drm_device_unregister(struct drm_device *dev)
{
struct exynos_drm_subdrv *subdrv;
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
if (!dev) {
WARN(1, "Unexpected drm device unregister!\n");
return -EINVAL;
@@ -176,8 +168,6 @@ EXPORT_SYMBOL_GPL(exynos_drm_device_unregister);
int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
if (!subdrv)
return -EINVAL;
@@ -189,8 +179,6 @@ EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register);
int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
if (!subdrv)
return -EINVAL;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 073c10a35b2a..9a35d171a6d3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -76,8 +76,6 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* drm framework doesn't check NULL. */
}
@@ -85,8 +83,6 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
exynos_plane_commit(exynos_crtc->plane);
exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON);
@@ -97,8 +93,6 @@ exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* drm framework doesn't check NULL */
return true;
}
@@ -115,8 +109,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
int pipe = exynos_crtc->pipe;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* copy the mode data adjusted by mode_fixup() into crtc->mode
* so that hardware can be seet to proper mode.
@@ -139,7 +131,7 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
return 0;
}
-static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -148,8 +140,6 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
unsigned int crtc_h;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* when framebuffer changing is requested, crtc's dpms should be on */
if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
DRM_ERROR("failed framebuffer changing request.\n");
@@ -169,12 +159,16 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
+static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ return exynos_drm_crtc_mode_set_commit(crtc, x, y, old_fb);
+}
+
static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_OFF);
exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
}
@@ -199,8 +193,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb = crtc->fb;
int ret = -EINVAL;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* when the page flip is requested, crtc's dpms should be on */
if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
DRM_ERROR("failed page flip request.\n");
@@ -230,7 +222,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
spin_unlock_irq(&dev->event_lock);
crtc->fb = fb;
- ret = exynos_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y,
+ ret = exynos_drm_crtc_mode_set_commit(crtc, crtc->x, crtc->y,
NULL);
if (ret) {
crtc->fb = old_fb;
@@ -253,8 +245,6 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct exynos_drm_private *private = crtc->dev->dev_private;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
private->crtc[exynos_crtc->pipe] = NULL;
drm_crtc_cleanup(crtc);
@@ -269,8 +259,6 @@ static int exynos_drm_crtc_set_property(struct drm_crtc *crtc,
struct exynos_drm_private *dev_priv = dev->dev_private;
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (property == dev_priv->crtc_mode_property) {
enum exynos_crtc_mode mode = val;
@@ -315,8 +303,6 @@ static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc)
struct exynos_drm_private *dev_priv = dev->dev_private;
struct drm_property *prop;
- DRM_DEBUG_KMS("%s\n", __func__);
-
prop = dev_priv->crtc_mode_property;
if (!prop) {
prop = drm_property_create_enum(dev, 0, "mode", mode_names,
@@ -336,8 +322,6 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
struct exynos_drm_private *private = dev->dev_private;
struct drm_crtc *crtc;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
if (!exynos_crtc) {
DRM_ERROR("failed to allocate exynos crtc\n");
@@ -372,8 +356,6 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)
struct exynos_drm_crtc *exynos_crtc =
to_exynos_crtc(private->crtc[crtc]);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
return -EPERM;
@@ -389,8 +371,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
struct exynos_drm_crtc *exynos_crtc =
to_exynos_crtc(private->crtc[crtc]);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
return;
@@ -406,8 +386,6 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc)
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(drm_crtc);
unsigned long flags;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
spin_lock_irqsave(&dev->event_lock, flags);
list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index ff7f2a886a34..a0f997e0cbdf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -71,8 +71,6 @@ static struct sg_table *
unsigned int i;
int nents, ret;
- DRM_DEBUG_PRIME("%s\n", __FILE__);
-
/* just return current sgt if already requested. */
if (exynos_attach->dir == dir && exynos_attach->is_mapped)
return &exynos_attach->sgt;
@@ -133,8 +131,6 @@ static void exynos_dmabuf_release(struct dma_buf *dmabuf)
{
struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv;
- DRM_DEBUG_PRIME("%s\n", __FILE__);
-
/*
* exynos_dmabuf_release() call means that file object's
* f_count is 0 and it calls drm_gem_object_handle_unreference()
@@ -219,8 +215,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
struct exynos_drm_gem_buf *buffer;
int ret;
- DRM_DEBUG_PRIME("%s\n", __FILE__);
-
/* is this one of own objects? */
if (dma_buf->ops == &exynos_dmabuf_ops) {
struct drm_gem_object *obj;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index ba6d995e4375..276237348d1e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -46,8 +46,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
int ret;
int nr;
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
if (!private) {
DRM_ERROR("failed to allocate private\n");
@@ -140,8 +138,6 @@ err_crtc:
static int exynos_drm_unload(struct drm_device *dev)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
exynos_drm_fbdev_fini(dev);
exynos_drm_device_unregister(dev);
drm_vblank_cleanup(dev);
@@ -160,8 +156,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
{
struct drm_exynos_file_private *file_priv;
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
if (!file_priv)
return -ENOMEM;
@@ -178,8 +172,6 @@ static void exynos_drm_preclose(struct drm_device *dev,
struct drm_pending_vblank_event *e, *t;
unsigned long flags;
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
/* release events of current file */
spin_lock_irqsave(&dev->event_lock, flags);
list_for_each_entry_safe(e, t, &private->pageflip_event_list,
@@ -196,8 +188,6 @@ static void exynos_drm_preclose(struct drm_device *dev,
static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
if (!file->driver_priv)
return;
@@ -207,8 +197,6 @@ static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
static void exynos_drm_lastclose(struct drm_device *dev)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
exynos_drm_fbdev_restore_mode(dev);
}
@@ -292,8 +280,6 @@ static struct drm_driver exynos_drm_driver = {
static int exynos_drm_platform_probe(struct platform_device *pdev)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls);
@@ -302,8 +288,6 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
static int exynos_drm_platform_remove(struct platform_device *pdev)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
drm_platform_exit(&exynos_drm_driver, pdev);
return 0;
@@ -322,8 +306,6 @@ static int __init exynos_drm_init(void)
{
int ret;
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
#ifdef CONFIG_DRM_EXYNOS_FIMD
ret = platform_driver_register(&fimd_driver);
if (ret < 0)
@@ -455,8 +437,6 @@ out_fimd:
static void __exit exynos_drm_exit(void)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
platform_device_unregister(exynos_drm_pdev);
platform_driver_unregister(&exynos_drm_platform_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 680a7c1b9dea..eaa19668bf00 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -142,7 +142,7 @@ struct exynos_drm_overlay {
* @is_connected: check for that display is connected or not.
* @get_edid: get edid modes from display driver.
* @get_panel: get panel object from display driver.
- * @check_timing: check if timing is valid or not.
+ * @check_mode: check if mode is valid or not.
* @power_on: display device on or off.
*/
struct exynos_drm_display_ops {
@@ -151,7 +151,7 @@ struct exynos_drm_display_ops {
struct edid *(*get_edid)(struct device *dev,
struct drm_connector *connector);
void *(*get_panel)(struct device *dev);
- int (*check_timing)(struct device *dev, void *timing);
+ int (*check_mode)(struct device *dev, struct drm_display_mode *mode);
int (*power_on)(struct device *dev, int mode);
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index c63721f64aec..a99a033793bc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -61,7 +61,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
struct exynos_drm_manager_ops *manager_ops = manager->ops;
struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
- DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode);
+ DRM_DEBUG_KMS("encoder dpms: %d\n", mode);
if (exynos_encoder->dpms == mode) {
DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
@@ -104,8 +104,6 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
struct exynos_drm_manager_ops *manager_ops = manager->ops;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->encoder == encoder)
if (manager_ops && manager_ops->mode_fixup)
@@ -155,8 +153,6 @@ static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
struct exynos_drm_manager *manager;
struct exynos_drm_manager_ops *manager_ops;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->encoder == encoder) {
struct exynos_drm_encoder *exynos_encoder;
@@ -189,8 +185,6 @@ static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* drm framework doesn't check NULL. */
}
@@ -200,8 +194,6 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
struct exynos_drm_manager *manager = exynos_encoder->manager;
struct exynos_drm_manager_ops *manager_ops = manager->ops;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (manager_ops && manager_ops->commit)
manager_ops->commit(manager->dev);
@@ -274,8 +266,6 @@ static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
struct exynos_drm_encoder *exynos_encoder =
to_exynos_encoder(encoder);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_encoder->manager->pipe = -1;
drm_encoder_cleanup(encoder);
@@ -315,8 +305,6 @@ void exynos_drm_encoder_setup(struct drm_device *dev)
{
struct drm_encoder *encoder;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
encoder->possible_clones = exynos_drm_encoder_clones(encoder);
}
@@ -329,8 +317,6 @@ exynos_drm_encoder_create(struct drm_device *dev,
struct drm_encoder *encoder;
struct exynos_drm_encoder *exynos_encoder;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (!manager || !possible_crtcs)
return NULL;
@@ -427,8 +413,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
struct exynos_drm_manager_ops *manager_ops = manager->ops;
int mode = *(int *)data;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (manager_ops && manager_ops->dpms)
manager_ops->dpms(manager->dev, mode);
@@ -449,8 +433,6 @@ void exynos_drm_encoder_crtc_pipe(struct drm_encoder *encoder, void *data)
to_exynos_encoder(encoder)->manager;
int pipe = *(int *)data;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* when crtc is detached from encoder, this pipe is used
* to select manager operation
@@ -465,8 +447,6 @@ void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data)
struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
struct exynos_drm_overlay *overlay = data;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (overlay_ops && overlay_ops->mode_set)
overlay_ops->mode_set(manager->dev, overlay);
}
@@ -478,8 +458,6 @@ void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data)
struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
int zpos = DEFAULT_ZPOS;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (data)
zpos = *(int *)data;
@@ -494,8 +472,6 @@ void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data)
struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
int zpos = DEFAULT_ZPOS;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (data)
zpos = *(int *)data;
@@ -510,8 +486,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
int zpos = DEFAULT_ZPOS;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (data)
zpos = *(int *)data;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 0e04f4ea441f..c2d149f0408a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -70,8 +70,6 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
unsigned int i;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* make sure that overlay data are updated before relesing fb. */
exynos_drm_encoder_complete_scanout(fb);
@@ -97,8 +95,6 @@ static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* This fb should have only one gem object. */
if (WARN_ON(exynos_fb->buf_cnt != 1))
return -EINVAL;
@@ -112,8 +108,6 @@ static int exynos_drm_fb_dirty(struct drm_framebuffer *fb,
unsigned color, struct drm_clip_rect *clips,
unsigned num_clips)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO */
return 0;
@@ -225,8 +219,6 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
struct exynos_drm_fb *exynos_fb;
int i, ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
if (!exynos_fb) {
DRM_ERROR("failed to allocate exynos drm framebuffer\n");
@@ -293,8 +285,6 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
struct exynos_drm_gem_buf *buffer;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (index >= MAX_FB_BUFFER)
return NULL;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 8f007aaeffc3..8e60bd61137f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -43,8 +43,6 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
unsigned long vm_size;
int ret;
- DRM_DEBUG_KMS("%s\n", __func__);
-
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vm_size = vma->vm_end - vma->vm_start;
@@ -84,8 +82,6 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
unsigned long offset;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
@@ -148,8 +144,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
unsigned long size;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n",
sizes->surface_width, sizes->surface_height,
sizes->surface_bpp);
@@ -238,8 +232,6 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
unsigned int num_crtc;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 4a1616a18ab7..61b094f689a7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -175,8 +175,6 @@ static void fimc_sw_reset(struct fimc_context *ctx)
{
u32 cfg;
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* stop dma operation */
cfg = fimc_read(EXYNOS_CISTATUS);
if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) {
@@ -210,8 +208,6 @@ static void fimc_sw_reset(struct fimc_context *ctx)
static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)
{
- DRM_DEBUG_KMS("%s\n", __func__);
-
return regmap_update_bits(ctx->sysreg, SYSREG_CAMERA_BLK,
SYSREG_FIMD0WB_DEST_MASK,
ctx->id << SYSREG_FIMD0WB_DEST_SHIFT);
@@ -221,7 +217,7 @@ static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
{
u32 cfg;
- DRM_DEBUG_KMS("%s:wb[%d]\n", __func__, wb);
+ DRM_DEBUG_KMS("wb[%d]\n", wb);
cfg = fimc_read(EXYNOS_CIGCTRL);
cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK |
@@ -257,10 +253,10 @@ static void fimc_set_polarity(struct fimc_context *ctx,
{
u32 cfg;
- DRM_DEBUG_KMS("%s:inv_pclk[%d]inv_vsync[%d]\n",
- __func__, pol->inv_pclk, pol->inv_vsync);
- DRM_DEBUG_KMS("%s:inv_href[%d]inv_hsync[%d]\n",
- __func__, pol->inv_href, pol->inv_hsync);
+ DRM_DEBUG_KMS("inv_pclk[%d]inv_vsync[%d]\n",
+ pol->inv_pclk, pol->inv_vsync);
+ DRM_DEBUG_KMS("inv_href[%d]inv_hsync[%d]\n",
+ pol->inv_href, pol->inv_hsync);
cfg = fimc_read(EXYNOS_CIGCTRL);
cfg &= ~(EXYNOS_CIGCTRL_INVPOLPCLK | EXYNOS_CIGCTRL_INVPOLVSYNC |
@@ -282,7 +278,7 @@ static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
{
u32 cfg;
- DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+ DRM_DEBUG_KMS("enable[%d]\n", enable);
cfg = fimc_read(EXYNOS_CIGCTRL);
if (enable)
@@ -298,7 +294,7 @@ static void fimc_handle_irq(struct fimc_context *ctx, bool enable,
{
u32 cfg;
- DRM_DEBUG_KMS("%s:enable[%d]overflow[%d]level[%d]\n", __func__,
+ DRM_DEBUG_KMS("enable[%d]overflow[%d]level[%d]\n",
enable, overflow, level);
cfg = fimc_read(EXYNOS_CIGCTRL);
@@ -319,8 +315,6 @@ static void fimc_clear_irq(struct fimc_context *ctx)
{
u32 cfg;
- DRM_DEBUG_KMS("%s\n", __func__);
-
cfg = fimc_read(EXYNOS_CIGCTRL);
cfg |= EXYNOS_CIGCTRL_IRQ_CLR;
fimc_write(cfg, EXYNOS_CIGCTRL);
@@ -335,7 +329,7 @@ static bool fimc_check_ovf(struct fimc_context *ctx)
flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB |
EXYNOS_CISTATUS_OVFICR;
- DRM_DEBUG_KMS("%s:flag[0x%x]\n", __func__, flag);
+ DRM_DEBUG_KMS("flag[0x%x]\n", flag);
if (status & flag) {
cfg = fimc_read(EXYNOS_CIWDOFST);
@@ -364,7 +358,7 @@ static bool fimc_check_frame_end(struct fimc_context *ctx)
cfg = fimc_read(EXYNOS_CISTATUS);
- DRM_DEBUG_KMS("%s:cfg[0x%x]\n", __func__, cfg);
+ DRM_DEBUG_KMS("cfg[0x%x]\n", cfg);
if (!(cfg & EXYNOS_CISTATUS_FRAMEEND))
return false;
@@ -380,15 +374,13 @@ static int fimc_get_buf_id(struct fimc_context *ctx)
u32 cfg;
int frame_cnt, buf_id;
- DRM_DEBUG_KMS("%s\n", __func__);
-
cfg = fimc_read(EXYNOS_CISTATUS2);
frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg);
if (frame_cnt == 0)
frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg);
- DRM_DEBUG_KMS("%s:present[%d]before[%d]\n", __func__,
+ DRM_DEBUG_KMS("present[%d]before[%d]\n",
EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg),
EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg));
@@ -398,7 +390,7 @@ static int fimc_get_buf_id(struct fimc_context *ctx)
}
buf_id = frame_cnt - 1;
- DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, buf_id);
+ DRM_DEBUG_KMS("buf_id[%d]\n", buf_id);
return buf_id;
}
@@ -407,7 +399,7 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
{
u32 cfg;
- DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+ DRM_DEBUG_KMS("enable[%d]\n", enable);
cfg = fimc_read(EXYNOS_CIOCTRL);
if (enable)
@@ -424,7 +416,7 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+ DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
/* RGB */
cfg = fimc_read(EXYNOS_CISCCTRL);
@@ -497,7 +489,7 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+ DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
cfg = fimc_read(EXYNOS_MSCTRL);
cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB;
@@ -557,8 +549,7 @@ static int fimc_src_set_transf(struct device *dev,
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg1, cfg2;
- DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
- degree, flip);
+ DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
cfg1 = fimc_read(EXYNOS_MSCTRL);
cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR |
@@ -621,10 +612,9 @@ static int fimc_set_window(struct fimc_context *ctx,
v1 = pos->y;
v2 = sz->vsize - pos->h - pos->y;
- DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
- __func__, pos->x, pos->y, pos->w, pos->h, sz->hsize, sz->vsize);
- DRM_DEBUG_KMS("%s:h1[%d]h2[%d]v1[%d]v2[%d]\n", __func__,
- h1, h2, v1, v2);
+ DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
+ pos->x, pos->y, pos->w, pos->h, sz->hsize, sz->vsize);
+ DRM_DEBUG_KMS("h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, v2);
/*
* set window offset 1, 2 size
@@ -653,8 +643,8 @@ static int fimc_src_set_size(struct device *dev, int swap,
struct drm_exynos_sz img_sz = *sz;
u32 cfg;
- DRM_DEBUG_KMS("%s:swap[%d]hsize[%d]vsize[%d]\n",
- __func__, swap, sz->hsize, sz->vsize);
+ DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n",
+ swap, sz->hsize, sz->vsize);
/* original size */
cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) |
@@ -662,8 +652,7 @@ static int fimc_src_set_size(struct device *dev, int swap,
fimc_write(cfg, EXYNOS_ORGISIZE);
- DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n", __func__,
- pos->x, pos->y, pos->w, pos->h);
+ DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h);
if (swap) {
img_pos.w = pos->h;
@@ -720,7 +709,7 @@ static int fimc_src_set_addr(struct device *dev,
property = &c_node->property;
- DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+ DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
property->prop_id, buf_id, buf_type);
if (buf_id > FIMC_MAX_SRC) {
@@ -772,7 +761,7 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+ DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
/* RGB */
cfg = fimc_read(EXYNOS_CISCCTRL);
@@ -851,7 +840,7 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+ DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
cfg = fimc_read(EXYNOS_CIEXTEN);
@@ -919,8 +908,7 @@ static int fimc_dst_set_transf(struct device *dev,
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
- degree, flip);
+ DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
cfg = fimc_read(EXYNOS_CITRGFMT);
cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK;
@@ -970,7 +958,7 @@ static int fimc_dst_set_transf(struct device *dev,
static int fimc_get_ratio_shift(u32 src, u32 dst, u32 *ratio, u32 *shift)
{
- DRM_DEBUG_KMS("%s:src[%d]dst[%d]\n", __func__, src, dst);
+ DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst);
if (src >= dst * 64) {
DRM_ERROR("failed to make ratio and shift.\n");
@@ -1039,20 +1027,20 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
pre_dst_width = src_w / pre_hratio;
pre_dst_height = src_h / pre_vratio;
- DRM_DEBUG_KMS("%s:pre_dst_width[%d]pre_dst_height[%d]\n", __func__,
+ DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n",
pre_dst_width, pre_dst_height);
- DRM_DEBUG_KMS("%s:pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n",
- __func__, pre_hratio, hfactor, pre_vratio, vfactor);
+ DRM_DEBUG_KMS("pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n",
+ pre_hratio, hfactor, pre_vratio, vfactor);
sc->hratio = (src_w << 14) / (dst_w << hfactor);
sc->vratio = (src_h << 14) / (dst_h << vfactor);
sc->up_h = (dst_w >= src_w) ? true : false;
sc->up_v = (dst_h >= src_h) ? true : false;
- DRM_DEBUG_KMS("%s:hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
- __func__, sc->hratio, sc->vratio, sc->up_h, sc->up_v);
+ DRM_DEBUG_KMS("hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
+ sc->hratio, sc->vratio, sc->up_h, sc->up_v);
shfactor = FIMC_SHFACTOR - (hfactor + vfactor);
- DRM_DEBUG_KMS("%s:shfactor[%d]\n", __func__, shfactor);
+ DRM_DEBUG_KMS("shfactor[%d]\n", shfactor);
cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
EXYNOS_CISCPRERATIO_PREHORRATIO(pre_hratio) |
@@ -1070,10 +1058,10 @@ static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
{
u32 cfg, cfg_ext;
- DRM_DEBUG_KMS("%s:range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
- __func__, sc->range, sc->bypass, sc->up_h, sc->up_v);
- DRM_DEBUG_KMS("%s:hratio[%d]vratio[%d]\n",
- __func__, sc->hratio, sc->vratio);
+ DRM_DEBUG_KMS("range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
+ sc->range, sc->bypass, sc->up_h, sc->up_v);
+ DRM_DEBUG_KMS("hratio[%d]vratio[%d]\n",
+ sc->hratio, sc->vratio);
cfg = fimc_read(EXYNOS_CISCCTRL);
cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS |
@@ -1113,8 +1101,8 @@ static int fimc_dst_set_size(struct device *dev, int swap,
struct drm_exynos_sz img_sz = *sz;
u32 cfg;
- DRM_DEBUG_KMS("%s:swap[%d]hsize[%d]vsize[%d]\n",
- __func__, swap, sz->hsize, sz->vsize);
+ DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n",
+ swap, sz->hsize, sz->vsize);
/* original size */
cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) |
@@ -1122,8 +1110,7 @@ static int fimc_dst_set_size(struct device *dev, int swap,
fimc_write(cfg, EXYNOS_ORGOSIZE);
- DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n",
- __func__, pos->x, pos->y, pos->w, pos->h);
+ DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h);
/* CSC ITU */
cfg = fimc_read(EXYNOS_CIGCTRL);
@@ -1180,7 +1167,7 @@ static int fimc_dst_get_buf_seq(struct fimc_context *ctx)
if (cfg & (mask << i))
buf_num++;
- DRM_DEBUG_KMS("%s:buf_num[%d]\n", __func__, buf_num);
+ DRM_DEBUG_KMS("buf_num[%d]\n", buf_num);
return buf_num;
}
@@ -1194,8 +1181,7 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
u32 mask = 0x00000001 << buf_id;
int ret = 0;
- DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
- buf_id, buf_type);
+ DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
mutex_lock(&ctx->lock);
@@ -1252,7 +1238,7 @@ static int fimc_dst_set_addr(struct device *dev,
property = &c_node->property;
- DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+ DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
property->prop_id, buf_id, buf_type);
if (buf_id > FIMC_MAX_DST) {
@@ -1302,7 +1288,7 @@ static struct exynos_drm_ipp_ops fimc_dst_ops = {
static int fimc_clk_ctrl(struct fimc_context *ctx, bool enable)
{
- DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+ DRM_DEBUG_KMS("enable[%d]\n", enable);
if (enable) {
clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]);
@@ -1326,7 +1312,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
c_node->event_work;
int buf_id;
- DRM_DEBUG_KMS("%s:fimc id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("fimc id[%d]\n", ctx->id);
fimc_clear_irq(ctx);
if (fimc_check_ovf(ctx))
@@ -1339,7 +1325,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
if (buf_id < 0)
return IRQ_HANDLED;
- DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, buf_id);
+ DRM_DEBUG_KMS("buf_id[%d]\n", buf_id);
if (fimc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE) < 0) {
DRM_ERROR("failed to dequeue.\n");
@@ -1357,8 +1343,6 @@ static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
{
struct drm_exynos_ipp_prop_list *prop_list;
- DRM_DEBUG_KMS("%s\n", __func__);
-
prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
if (!prop_list) {
DRM_ERROR("failed to alloc property list.\n");
@@ -1402,7 +1386,7 @@ static inline bool fimc_check_drm_flip(enum drm_exynos_flip flip)
case EXYNOS_DRM_FLIP_BOTH:
return true;
default:
- DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+ DRM_DEBUG_KMS("invalid flip\n");
return false;
}
}
@@ -1419,8 +1403,6 @@ static int fimc_ippdrv_check_property(struct device *dev,
bool swap;
int i;
- DRM_DEBUG_KMS("%s\n", __func__);
-
for_each_ipp_ops(i) {
if ((i == EXYNOS_DRM_OPS_SRC) &&
(property->cmd == IPP_CMD_WB))
@@ -1526,8 +1508,6 @@ static void fimc_clear_addr(struct fimc_context *ctx)
{
int i;
- DRM_DEBUG_KMS("%s:\n", __func__);
-
for (i = 0; i < FIMC_MAX_SRC; i++) {
fimc_write(0, EXYNOS_CIIYSA(i));
fimc_write(0, EXYNOS_CIICBSA(i));
@@ -1545,8 +1525,6 @@ static int fimc_ippdrv_reset(struct device *dev)
{
struct fimc_context *ctx = get_fimc_context(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* reset h/w block */
fimc_sw_reset(ctx);
@@ -1570,7 +1548,7 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
int ret, i;
u32 cfg0, cfg1;
- DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+ DRM_DEBUG_KMS("cmd[%d]\n", cmd);
if (!c_node) {
DRM_ERROR("failed to get c_node.\n");
@@ -1679,7 +1657,7 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
struct drm_exynos_ipp_set_wb set_wb = {0, 0};
u32 cfg;
- DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+ DRM_DEBUG_KMS("cmd[%d]\n", cmd);
switch (cmd) {
case IPP_CMD_M2M:
@@ -1869,8 +1847,7 @@ static int fimc_probe(struct platform_device *pdev)
goto err_put_clk;
}
- DRM_DEBUG_KMS("%s:id[%d]ippdrv[0x%x]\n", __func__, ctx->id,
- (int)ippdrv);
+ DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
mutex_init(&ctx->lock);
platform_set_drvdata(pdev, ctx);
@@ -1917,7 +1894,7 @@ static int fimc_suspend(struct device *dev)
{
struct fimc_context *ctx = get_fimc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
if (pm_runtime_suspended(dev))
return 0;
@@ -1929,7 +1906,7 @@ static int fimc_resume(struct device *dev)
{
struct fimc_context *ctx = get_fimc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
if (!pm_runtime_suspended(dev))
return fimc_clk_ctrl(ctx, true);
@@ -1943,7 +1920,7 @@ static int fimc_runtime_suspend(struct device *dev)
{
struct fimc_context *ctx = get_fimc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
return fimc_clk_ctrl(ctx, false);
}
@@ -1952,7 +1929,7 @@ static int fimc_runtime_resume(struct device *dev)
{
struct fimc_context *ctx = get_fimc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
return fimc_clk_ctrl(ctx, true);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 97c61dbffd82..3e106beca5b6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -63,14 +63,24 @@
struct fimd_driver_data {
unsigned int timing_base;
+
+ unsigned int has_shadowcon:1;
+ unsigned int has_clksel:1;
+};
+
+static struct fimd_driver_data s3c64xx_fimd_driver_data = {
+ .timing_base = 0x0,
+ .has_clksel = 1,
};
static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
+ .has_shadowcon = 1,
};
static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x20000,
+ .has_shadowcon = 1,
};
struct fimd_win_data {
@@ -107,10 +117,13 @@ struct fimd_context {
atomic_t wait_vsync_event;
struct exynos_drm_panel_info *panel;
+ struct fimd_driver_data *driver_data;
};
#ifdef CONFIG_OF
static const struct of_device_id fimd_driver_dt_match[] = {
+ { .compatible = "samsung,s3c6400-fimd",
+ .data = &s3c64xx_fimd_driver_data },
{ .compatible = "samsung,exynos4210-fimd",
.data = &exynos4_fimd_driver_data },
{ .compatible = "samsung,exynos5250-fimd",
@@ -137,8 +150,6 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
static bool fimd_display_is_connected(struct device *dev)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO. */
return true;
@@ -148,15 +159,11 @@ static void *fimd_get_panel(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
return ctx->panel;
}
-static int fimd_check_timing(struct device *dev, void *timing)
+static int fimd_check_mode(struct device *dev, struct drm_display_mode *mode)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO. */
return 0;
@@ -164,8 +171,6 @@ static int fimd_check_timing(struct device *dev, void *timing)
static int fimd_display_power_on(struct device *dev, int mode)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO */
return 0;
@@ -175,7 +180,7 @@ static struct exynos_drm_display_ops fimd_display_ops = {
.type = EXYNOS_DISPLAY_TYPE_LCD,
.is_connected = fimd_display_is_connected,
.get_panel = fimd_get_panel,
- .check_timing = fimd_check_timing,
+ .check_mode = fimd_check_mode,
.power_on = fimd_display_power_on,
};
@@ -183,7 +188,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
{
struct fimd_context *ctx = get_fimd_context(subdrv_dev);
- DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
+ DRM_DEBUG_KMS("%d\n", mode);
mutex_lock(&ctx->lock);
@@ -221,8 +226,6 @@ static void fimd_apply(struct device *subdrv_dev)
struct fimd_win_data *win_data;
int i;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
if (win_data->enabled && (ovl_ops && ovl_ops->commit))
@@ -239,15 +242,12 @@ static void fimd_commit(struct device *dev)
struct exynos_drm_panel_info *panel = ctx->panel;
struct fb_videomode *timing = &panel->timing;
struct fimd_driver_data *driver_data;
- struct platform_device *pdev = to_platform_device(dev);
u32 val;
- driver_data = drm_fimd_get_driver_data(pdev);
+ driver_data = ctx->driver_data;
if (ctx->suspended)
return;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* setup polarity values from machine code. */
writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
@@ -274,6 +274,11 @@ static void fimd_commit(struct device *dev)
val = ctx->vidcon0;
val &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
+ if (ctx->driver_data->has_clksel) {
+ val &= ~VIDCON0_CLKSEL_MASK;
+ val |= VIDCON0_CLKSEL_LCD;
+ }
+
if (ctx->clkdiv > 1)
val |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1) | VIDCON0_CLKDIR;
else
@@ -292,8 +297,6 @@ static int fimd_enable_vblank(struct device *dev)
struct fimd_context *ctx = get_fimd_context(dev);
u32 val;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ctx->suspended)
return -EPERM;
@@ -319,8 +322,6 @@ static void fimd_disable_vblank(struct device *dev)
struct fimd_context *ctx = get_fimd_context(dev);
u32 val;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ctx->suspended)
return;
@@ -370,8 +371,6 @@ static void fimd_win_mode_set(struct device *dev,
int win;
unsigned long offset;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (!overlay) {
dev_err(dev, "overlay is NULL\n");
return;
@@ -381,7 +380,7 @@ static void fimd_win_mode_set(struct device *dev,
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
- if (win < 0 || win > WINDOWS_NR)
+ if (win < 0 || win >= WINDOWS_NR)
return;
offset = overlay->fb_x * (overlay->bpp >> 3);
@@ -418,8 +417,6 @@ static void fimd_win_set_pixfmt(struct device *dev, unsigned int win)
struct fimd_win_data *win_data = &ctx->win_data[win];
unsigned long val;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
val = WINCONx_ENWIN;
switch (win_data->bpp) {
@@ -478,8 +475,6 @@ static void fimd_win_set_colkey(struct device *dev, unsigned int win)
struct fimd_context *ctx = get_fimd_context(dev);
unsigned int keycon0 = 0, keycon1 = 0;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F |
WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0);
@@ -489,6 +484,33 @@ static void fimd_win_set_colkey(struct device *dev, unsigned int win)
writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
}
+/**
+ * shadow_protect_win() - disable updating values from shadow registers at vsync
+ *
+ * @win: window to protect registers for
+ * @protect: 1 to protect (disable updates)
+ */
+static void fimd_shadow_protect_win(struct fimd_context *ctx,
+ int win, bool protect)
+{
+ u32 reg, bits, val;
+
+ if (ctx->driver_data->has_shadowcon) {
+ reg = SHADOWCON;
+ bits = SHADOWCON_WINx_PROTECT(win);
+ } else {
+ reg = PRTCON;
+ bits = PRTCON_PROTECT;
+ }
+
+ val = readl(ctx->regs + reg);
+ if (protect)
+ val |= bits;
+ else
+ val &= ~bits;
+ writel(val, ctx->regs + reg);
+}
+
static void fimd_win_commit(struct device *dev, int zpos)
{
struct fimd_context *ctx = get_fimd_context(dev);
@@ -498,21 +520,19 @@ static void fimd_win_commit(struct device *dev, int zpos)
unsigned int last_x;
unsigned int last_y;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ctx->suspended)
return;
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
- if (win < 0 || win > WINDOWS_NR)
+ if (win < 0 || win >= WINDOWS_NR)
return;
win_data = &ctx->win_data[win];
/*
- * SHADOWCON register is used for enabling timing.
+ * SHADOWCON/PRTCON register is used for enabling timing.
*
* for example, once only width value of a register is set,
* if the dma is started then fimd hardware could malfunction so
@@ -522,9 +542,7 @@ static void fimd_win_commit(struct device *dev, int zpos)
*/
/* protect windows */
- val = readl(ctx->regs + SHADOWCON);
- val |= SHADOWCON_WINx_PROTECT(win);
- writel(val, ctx->regs + SHADOWCON);
+ fimd_shadow_protect_win(ctx, win, true);
/* buffer start address */
val = (unsigned long)win_data->dma_addr;
@@ -602,10 +620,13 @@ static void fimd_win_commit(struct device *dev, int zpos)
writel(val, ctx->regs + WINCON(win));
/* Enable DMA channel and unprotect windows */
- val = readl(ctx->regs + SHADOWCON);
- val |= SHADOWCON_CHx_ENABLE(win);
- val &= ~SHADOWCON_WINx_PROTECT(win);
- writel(val, ctx->regs + SHADOWCON);
+ fimd_shadow_protect_win(ctx, win, false);
+
+ if (ctx->driver_data->has_shadowcon) {
+ val = readl(ctx->regs + SHADOWCON);
+ val |= SHADOWCON_CHx_ENABLE(win);
+ writel(val, ctx->regs + SHADOWCON);
+ }
win_data->enabled = true;
}
@@ -617,12 +638,10 @@ static void fimd_win_disable(struct device *dev, int zpos)
int win = zpos;
u32 val;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
- if (win < 0 || win > WINDOWS_NR)
+ if (win < 0 || win >= WINDOWS_NR)
return;
win_data = &ctx->win_data[win];
@@ -634,9 +653,7 @@ static void fimd_win_disable(struct device *dev, int zpos)
}
/* protect windows */
- val = readl(ctx->regs + SHADOWCON);
- val |= SHADOWCON_WINx_PROTECT(win);
- writel(val, ctx->regs + SHADOWCON);
+ fimd_shadow_protect_win(ctx, win, true);
/* wincon */
val = readl(ctx->regs + WINCON(win));
@@ -644,10 +661,13 @@ static void fimd_win_disable(struct device *dev, int zpos)
writel(val, ctx->regs + WINCON(win));
/* unprotect windows */
- val = readl(ctx->regs + SHADOWCON);
- val &= ~SHADOWCON_CHx_ENABLE(win);
- val &= ~SHADOWCON_WINx_PROTECT(win);
- writel(val, ctx->regs + SHADOWCON);
+ if (ctx->driver_data->has_shadowcon) {
+ val = readl(ctx->regs + SHADOWCON);
+ val &= ~SHADOWCON_CHx_ENABLE(win);
+ writel(val, ctx->regs + SHADOWCON);
+ }
+
+ fimd_shadow_protect_win(ctx, win, false);
win_data->enabled = false;
}
@@ -697,8 +717,6 @@ out:
static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* enable drm irq mode.
* - with irq_enabled = 1, we can use the vblank feature.
@@ -725,8 +743,6 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
static void fimd_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* detach this sub driver from iommu mapping if supported. */
if (is_drm_iommu_supported(drm_dev))
drm_iommu_detach_device(drm_dev, dev);
@@ -741,8 +757,6 @@ static int fimd_calc_clkdiv(struct fimd_context *ctx,
u32 best_framerate = 0;
u32 framerate;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
retrace = timing->left_margin + timing->hsync_len +
timing->right_margin + timing->xres;
retrace *= timing->upper_margin + timing->vsync_len +
@@ -777,10 +791,6 @@ static int fimd_calc_clkdiv(struct fimd_context *ctx,
static void fimd_clear_win(struct fimd_context *ctx, int win)
{
- u32 val;
-
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
writel(0, ctx->regs + WINCON(win));
writel(0, ctx->regs + VIDOSD_A(win));
writel(0, ctx->regs + VIDOSD_B(win));
@@ -789,15 +799,11 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
if (win == 1 || win == 2)
writel(0, ctx->regs + VIDOSD_D(win));
- val = readl(ctx->regs + SHADOWCON);
- val &= ~SHADOWCON_WINx_PROTECT(win);
- writel(val, ctx->regs + SHADOWCON);
+ fimd_shadow_protect_win(ctx, win, false);
}
static int fimd_clock(struct fimd_context *ctx, bool enable)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (enable) {
int ret;
@@ -883,8 +889,6 @@ static int fimd_probe(struct platform_device *pdev)
int win;
int ret = -EINVAL;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (dev->of_node) {
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
@@ -949,6 +953,7 @@ static int fimd_probe(struct platform_device *pdev)
return ret;
}
+ ctx->driver_data = drm_fimd_get_driver_data(pdev);
ctx->vidcon0 = pdata->vidcon0;
ctx->vidcon1 = pdata->vidcon1;
ctx->default_win = pdata->default_win;
@@ -989,8 +994,6 @@ static int fimd_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct fimd_context *ctx = platform_get_drvdata(pdev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_drm_subdrv_unregister(&ctx->subdrv);
if (ctx->suspended)
@@ -1055,8 +1058,6 @@ static int fimd_runtime_suspend(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
return fimd_activate(ctx, false);
}
@@ -1064,14 +1065,15 @@ static int fimd_runtime_resume(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
return fimd_activate(ctx, true);
}
#endif
static struct platform_device_id fimd_driver_ids[] = {
{
+ .name = "s3c64xx-fb",
+ .driver_data = (unsigned long)&s3c64xx_fimd_driver_data,
+ }, {
.name = "exynos4-fb",
.driver_data = (unsigned long)&exynos4_fimd_driver_data,
}, {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index cf4543ffa079..c3f15e7646d5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -132,8 +132,6 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj)
struct drm_gem_object *obj;
struct exynos_drm_gem_buf *buf;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
obj = &exynos_gem_obj->base;
buf = exynos_gem_obj->buffer;
@@ -227,7 +225,6 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
}
size = roundup_gem_size(size, flags);
- DRM_DEBUG_KMS("%s\n", __FILE__);
ret = check_gem_flags(flags);
if (ret)
@@ -268,8 +265,6 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
struct exynos_drm_gem_obj *exynos_gem_obj;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
if (IS_ERR(exynos_gem_obj))
return PTR_ERR(exynos_gem_obj);
@@ -331,8 +326,6 @@ int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
{
struct drm_exynos_gem_map_off *args = data;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
DRM_DEBUG_KMS("handle = 0x%x, offset = 0x%lx\n",
args->handle, (unsigned long)args->offset);
@@ -371,8 +364,6 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
unsigned long vm_size;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = obj;
vma->vm_ops = drm_dev->driver->gem_vm_ops;
@@ -429,9 +420,7 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
{
struct drm_exynos_gem_mmap *args = data;
struct drm_gem_object *obj;
- unsigned int addr;
-
- DRM_DEBUG_KMS("%s\n", __FILE__);
+ unsigned long addr;
if (!(dev->driver->driver_features & DRIVER_GEM)) {
DRM_ERROR("does not support GEM.\n");
@@ -473,14 +462,14 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
drm_gem_object_unreference(obj);
- if (IS_ERR((void *)addr)) {
+ if (IS_ERR_VALUE(addr)) {
/* check filp->f_op, filp->private_data are restored */
if (file_priv->filp->f_op == &exynos_drm_gem_fops) {
file_priv->filp->f_op = fops_get(dev->driver->fops);
file_priv->filp->private_data = file_priv;
}
mutex_unlock(&dev->struct_mutex);
- return PTR_ERR((void *)addr);
+ return (int)addr;
}
mutex_unlock(&dev->struct_mutex);
@@ -643,8 +632,6 @@ void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
int exynos_drm_gem_init_object(struct drm_gem_object *obj)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
return 0;
}
@@ -653,8 +640,6 @@ void exynos_drm_gem_free_object(struct drm_gem_object *obj)
struct exynos_drm_gem_obj *exynos_gem_obj;
struct exynos_drm_gem_buf *buf;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_gem_obj = to_exynos_gem_obj(obj);
buf = exynos_gem_obj->buffer;
@@ -671,8 +656,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
struct exynos_drm_gem_obj *exynos_gem_obj;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* alocate memory to be used for framebuffer.
* - this callback would be called by user application
@@ -704,8 +687,6 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
struct drm_gem_object *obj;
int ret = 0;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
mutex_lock(&dev->struct_mutex);
/*
@@ -743,8 +724,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv,
{
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* obj->refcount and obj->handle_count are decreased and
* if both them are 0 then exynos_drm_gem_free_object()
@@ -788,8 +767,6 @@ int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_gem_object *obj;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* set vm_area_struct. */
ret = drm_gem_mmap(filp, vma);
if (ret < 0) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 762f40d548b7..472e3b25e7f2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -400,8 +400,6 @@ static int gsc_sw_reset(struct gsc_context *ctx)
u32 cfg;
int count = GSC_RESET_TIMEOUT;
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* s/w reset */
cfg = (GSC_SW_RESET_SRESET);
gsc_write(cfg, GSC_SW_RESET);
@@ -441,8 +439,6 @@ static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
{
u32 gscblk_cfg;
- DRM_DEBUG_KMS("%s\n", __func__);
-
gscblk_cfg = readl(SYSREG_GSCBLK_CFG1);
if (enable)
@@ -460,7 +456,7 @@ static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
{
u32 cfg;
- DRM_DEBUG_KMS("%s:enable[%d]overflow[%d]level[%d]\n", __func__,
+ DRM_DEBUG_KMS("enable[%d]overflow[%d]level[%d]\n",
enable, overflow, done);
cfg = gsc_read(GSC_IRQ);
@@ -491,7 +487,7 @@ static int gsc_src_set_fmt(struct device *dev, u32 fmt)
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+ DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
cfg = gsc_read(GSC_IN_CON);
cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK |
@@ -567,8 +563,7 @@ static int gsc_src_set_transf(struct device *dev,
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
- degree, flip);
+ DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
cfg = gsc_read(GSC_IN_CON);
cfg &= ~GSC_IN_ROT_MASK;
@@ -616,8 +611,8 @@ static int gsc_src_set_size(struct device *dev, int swap,
struct gsc_scaler *sc = &ctx->sc;
u32 cfg;
- DRM_DEBUG_KMS("%s:swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
- __func__, swap, pos->x, pos->y, pos->w, pos->h);
+ DRM_DEBUG_KMS("swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
+ swap, pos->x, pos->y, pos->w, pos->h);
if (swap) {
img_pos.w = pos->h;
@@ -634,8 +629,7 @@ static int gsc_src_set_size(struct device *dev, int swap,
GSC_CROPPED_HEIGHT(img_pos.h));
gsc_write(cfg, GSC_CROPPED_SIZE);
- DRM_DEBUG_KMS("%s:hsize[%d]vsize[%d]\n",
- __func__, sz->hsize, sz->vsize);
+ DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", sz->hsize, sz->vsize);
/* original size */
cfg = gsc_read(GSC_SRCIMG_SIZE);
@@ -650,8 +644,7 @@ static int gsc_src_set_size(struct device *dev, int swap,
cfg = gsc_read(GSC_IN_CON);
cfg &= ~GSC_IN_RGB_TYPE_MASK;
- DRM_DEBUG_KMS("%s:width[%d]range[%d]\n",
- __func__, pos->w, sc->range);
+ DRM_DEBUG_KMS("width[%d]range[%d]\n", pos->w, sc->range);
if (pos->w >= GSC_WIDTH_ITU_709)
if (sc->range)
@@ -677,8 +670,7 @@ static int gsc_src_set_buf_seq(struct gsc_context *ctx, u32 buf_id,
u32 cfg;
u32 mask = 0x00000001 << buf_id;
- DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
- buf_id, buf_type);
+ DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
/* mask register set */
cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
@@ -721,7 +713,7 @@ static int gsc_src_set_addr(struct device *dev,
property = &c_node->property;
- DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+ DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
property->prop_id, buf_id, buf_type);
if (buf_id > GSC_MAX_SRC) {
@@ -765,7 +757,7 @@ static int gsc_dst_set_fmt(struct device *dev, u32 fmt)
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+ DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
cfg = gsc_read(GSC_OUT_CON);
cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK |
@@ -838,8 +830,7 @@ static int gsc_dst_set_transf(struct device *dev,
struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
u32 cfg;
- DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
- degree, flip);
+ DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
cfg = gsc_read(GSC_IN_CON);
cfg &= ~GSC_IN_ROT_MASK;
@@ -881,7 +872,7 @@ static int gsc_dst_set_transf(struct device *dev,
static int gsc_get_ratio_shift(u32 src, u32 dst, u32 *ratio)
{
- DRM_DEBUG_KMS("%s:src[%d]dst[%d]\n", __func__, src, dst);
+ DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst);
if (src >= dst * 8) {
DRM_ERROR("failed to make ratio and shift.\n");
@@ -944,20 +935,19 @@ static int gsc_set_prescaler(struct gsc_context *ctx, struct gsc_scaler *sc,
return ret;
}
- DRM_DEBUG_KMS("%s:pre_hratio[%d]pre_vratio[%d]\n",
- __func__, sc->pre_hratio, sc->pre_vratio);
+ DRM_DEBUG_KMS("pre_hratio[%d]pre_vratio[%d]\n",
+ sc->pre_hratio, sc->pre_vratio);
sc->main_hratio = (src_w << 16) / dst_w;
sc->main_vratio = (src_h << 16) / dst_h;
- DRM_DEBUG_KMS("%s:main_hratio[%ld]main_vratio[%ld]\n",
- __func__, sc->main_hratio, sc->main_vratio);
+ DRM_DEBUG_KMS("main_hratio[%ld]main_vratio[%ld]\n",
+ sc->main_hratio, sc->main_vratio);
gsc_get_prescaler_shfactor(sc->pre_hratio, sc->pre_vratio,
&sc->pre_shfactor);
- DRM_DEBUG_KMS("%s:pre_shfactor[%d]\n", __func__,
- sc->pre_shfactor);
+ DRM_DEBUG_KMS("pre_shfactor[%d]\n", sc->pre_shfactor);
cfg = (GSC_PRESC_SHFACTOR(sc->pre_shfactor) |
GSC_PRESC_H_RATIO(sc->pre_hratio) |
@@ -1023,8 +1013,8 @@ static void gsc_set_scaler(struct gsc_context *ctx, struct gsc_scaler *sc)
{
u32 cfg;
- DRM_DEBUG_KMS("%s:main_hratio[%ld]main_vratio[%ld]\n",
- __func__, sc->main_hratio, sc->main_vratio);
+ DRM_DEBUG_KMS("main_hratio[%ld]main_vratio[%ld]\n",
+ sc->main_hratio, sc->main_vratio);
gsc_set_h_coef(ctx, sc->main_hratio);
cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio);
@@ -1043,8 +1033,8 @@ static int gsc_dst_set_size(struct device *dev, int swap,
struct gsc_scaler *sc = &ctx->sc;
u32 cfg;
- DRM_DEBUG_KMS("%s:swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
- __func__, swap, pos->x, pos->y, pos->w, pos->h);
+ DRM_DEBUG_KMS("swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
+ swap, pos->x, pos->y, pos->w, pos->h);
if (swap) {
img_pos.w = pos->h;
@@ -1060,8 +1050,7 @@ static int gsc_dst_set_size(struct device *dev, int swap,
cfg = (GSC_SCALED_WIDTH(img_pos.w) | GSC_SCALED_HEIGHT(img_pos.h));
gsc_write(cfg, GSC_SCALED_SIZE);
- DRM_DEBUG_KMS("%s:hsize[%d]vsize[%d]\n",
- __func__, sz->hsize, sz->vsize);
+ DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", sz->hsize, sz->vsize);
/* original size */
cfg = gsc_read(GSC_DSTIMG_SIZE);
@@ -1074,8 +1063,7 @@ static int gsc_dst_set_size(struct device *dev, int swap,
cfg = gsc_read(GSC_OUT_CON);
cfg &= ~GSC_OUT_RGB_TYPE_MASK;
- DRM_DEBUG_KMS("%s:width[%d]range[%d]\n",
- __func__, pos->w, sc->range);
+ DRM_DEBUG_KMS("width[%d]range[%d]\n", pos->w, sc->range);
if (pos->w >= GSC_WIDTH_ITU_709)
if (sc->range)
@@ -1104,7 +1092,7 @@ static int gsc_dst_get_buf_seq(struct gsc_context *ctx)
if (cfg & (mask << i))
buf_num--;
- DRM_DEBUG_KMS("%s:buf_num[%d]\n", __func__, buf_num);
+ DRM_DEBUG_KMS("buf_num[%d]\n", buf_num);
return buf_num;
}
@@ -1118,8 +1106,7 @@ static int gsc_dst_set_buf_seq(struct gsc_context *ctx, u32 buf_id,
u32 mask = 0x00000001 << buf_id;
int ret = 0;
- DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
- buf_id, buf_type);
+ DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
mutex_lock(&ctx->lock);
@@ -1177,7 +1164,7 @@ static int gsc_dst_set_addr(struct device *dev,
property = &c_node->property;
- DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+ DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
property->prop_id, buf_id, buf_type);
if (buf_id > GSC_MAX_DST) {
@@ -1217,7 +1204,7 @@ static struct exynos_drm_ipp_ops gsc_dst_ops = {
static int gsc_clk_ctrl(struct gsc_context *ctx, bool enable)
{
- DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+ DRM_DEBUG_KMS("enable[%d]\n", enable);
if (enable) {
clk_enable(ctx->gsc_clk);
@@ -1236,7 +1223,7 @@ static int gsc_get_src_buf_index(struct gsc_context *ctx)
u32 buf_id = GSC_MAX_SRC;
int ret;
- DRM_DEBUG_KMS("%s:gsc id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
curr_index = GSC_IN_CURR_GET_INDEX(cfg);
@@ -1259,7 +1246,7 @@ static int gsc_get_src_buf_index(struct gsc_context *ctx)
return ret;
}
- DRM_DEBUG_KMS("%s:cfg[0x%x]curr_index[%d]buf_id[%d]\n", __func__, cfg,
+ DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
curr_index, buf_id);
return buf_id;
@@ -1271,7 +1258,7 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx)
u32 buf_id = GSC_MAX_DST;
int ret;
- DRM_DEBUG_KMS("%s:gsc id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
curr_index = GSC_OUT_CURR_GET_INDEX(cfg);
@@ -1294,7 +1281,7 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx)
return ret;
}
- DRM_DEBUG_KMS("%s:cfg[0x%x]curr_index[%d]buf_id[%d]\n", __func__, cfg,
+ DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
curr_index, buf_id);
return buf_id;
@@ -1310,7 +1297,7 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id)
u32 status;
int buf_id[EXYNOS_DRM_OPS_MAX];
- DRM_DEBUG_KMS("%s:gsc id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
status = gsc_read(GSC_IRQ);
if (status & GSC_IRQ_STATUS_OR_IRQ) {
@@ -1331,7 +1318,7 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id)
if (buf_id[EXYNOS_DRM_OPS_DST] < 0)
return IRQ_HANDLED;
- DRM_DEBUG_KMS("%s:buf_id_src[%d]buf_id_dst[%d]\n", __func__,
+ DRM_DEBUG_KMS("buf_id_src[%d]buf_id_dst[%d]\n",
buf_id[EXYNOS_DRM_OPS_SRC], buf_id[EXYNOS_DRM_OPS_DST]);
event_work->ippdrv = ippdrv;
@@ -1350,8 +1337,6 @@ static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
{
struct drm_exynos_ipp_prop_list *prop_list;
- DRM_DEBUG_KMS("%s\n", __func__);
-
prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
if (!prop_list) {
DRM_ERROR("failed to alloc property list.\n");
@@ -1394,7 +1379,7 @@ static inline bool gsc_check_drm_flip(enum drm_exynos_flip flip)
case EXYNOS_DRM_FLIP_BOTH:
return true;
default:
- DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+ DRM_DEBUG_KMS("invalid flip\n");
return false;
}
}
@@ -1411,8 +1396,6 @@ static int gsc_ippdrv_check_property(struct device *dev,
bool swap;
int i;
- DRM_DEBUG_KMS("%s\n", __func__);
-
for_each_ipp_ops(i) {
if ((i == EXYNOS_DRM_OPS_SRC) &&
(property->cmd == IPP_CMD_WB))
@@ -1521,8 +1504,6 @@ static int gsc_ippdrv_reset(struct device *dev)
struct gsc_scaler *sc = &ctx->sc;
int ret;
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* reset h/w block */
ret = gsc_sw_reset(ctx);
if (ret < 0) {
@@ -1549,7 +1530,7 @@ static int gsc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
u32 cfg;
int ret, i;
- DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+ DRM_DEBUG_KMS("cmd[%d]\n", cmd);
if (!c_node) {
DRM_ERROR("failed to get c_node.\n");
@@ -1643,7 +1624,7 @@ static void gsc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
struct drm_exynos_ipp_set_wb set_wb = {0, 0};
u32 cfg;
- DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+ DRM_DEBUG_KMS("cmd[%d]\n", cmd);
switch (cmd) {
case IPP_CMD_M2M:
@@ -1728,8 +1709,7 @@ static int gsc_probe(struct platform_device *pdev)
return ret;
}
- DRM_DEBUG_KMS("%s:id[%d]ippdrv[0x%x]\n", __func__, ctx->id,
- (int)ippdrv);
+ DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
mutex_init(&ctx->lock);
platform_set_drvdata(pdev, ctx);
@@ -1772,7 +1752,7 @@ static int gsc_suspend(struct device *dev)
{
struct gsc_context *ctx = get_gsc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
if (pm_runtime_suspended(dev))
return 0;
@@ -1784,7 +1764,7 @@ static int gsc_resume(struct device *dev)
{
struct gsc_context *ctx = get_gsc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
if (!pm_runtime_suspended(dev))
return gsc_clk_ctrl(ctx, true);
@@ -1798,7 +1778,7 @@ static int gsc_runtime_suspend(struct device *dev)
{
struct gsc_context *ctx = get_gsc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
return gsc_clk_ctrl(ctx, false);
}
@@ -1807,7 +1787,7 @@ static int gsc_runtime_resume(struct device *dev)
{
struct gsc_context *ctx = get_gsc_context(dev);
- DRM_DEBUG_KMS("%s:id[%d]\n", __FILE__, ctx->id);
+ DRM_DEBUG_KMS("id[%d]\n", ctx->id);
return gsc_clk_ctrl(ctx, true);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index 437fb947e46d..aaa550d622f0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -88,16 +88,12 @@ void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx)
void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ops)
hdmi_ops = ops;
}
void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ops)
mixer_ops = ops;
}
@@ -106,8 +102,6 @@ static bool drm_hdmi_is_connected(struct device *dev)
{
struct drm_hdmi_context *ctx = to_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (hdmi_ops && hdmi_ops->is_connected)
return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
@@ -119,34 +113,31 @@ static struct edid *drm_hdmi_get_edid(struct device *dev,
{
struct drm_hdmi_context *ctx = to_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (hdmi_ops && hdmi_ops->get_edid)
return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector);
return NULL;
}
-static int drm_hdmi_check_timing(struct device *dev, void *timing)
+static int drm_hdmi_check_mode(struct device *dev,
+ struct drm_display_mode *mode)
{
struct drm_hdmi_context *ctx = to_context(dev);
int ret = 0;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* Both, mixer and hdmi should be able to handle the requested mode.
* If any of the two fails, return mode as BAD.
*/
- if (mixer_ops && mixer_ops->check_timing)
- ret = mixer_ops->check_timing(ctx->mixer_ctx->ctx, timing);
+ if (mixer_ops && mixer_ops->check_mode)
+ ret = mixer_ops->check_mode(ctx->mixer_ctx->ctx, mode);
if (ret)
return ret;
- if (hdmi_ops && hdmi_ops->check_timing)
- return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
+ if (hdmi_ops && hdmi_ops->check_mode)
+ return hdmi_ops->check_mode(ctx->hdmi_ctx->ctx, mode);
return 0;
}
@@ -155,8 +146,6 @@ static int drm_hdmi_power_on(struct device *dev, int mode)
{
struct drm_hdmi_context *ctx = to_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (hdmi_ops && hdmi_ops->power_on)
return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
@@ -167,7 +156,7 @@ static struct exynos_drm_display_ops drm_hdmi_display_ops = {
.type = EXYNOS_DISPLAY_TYPE_HDMI,
.is_connected = drm_hdmi_is_connected,
.get_edid = drm_hdmi_get_edid,
- .check_timing = drm_hdmi_check_timing,
+ .check_mode = drm_hdmi_check_mode,
.power_on = drm_hdmi_power_on,
};
@@ -177,8 +166,6 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev)
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct exynos_drm_manager *manager = subdrv->manager;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (mixer_ops && mixer_ops->enable_vblank)
return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
manager->pipe);
@@ -190,8 +177,6 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (mixer_ops && mixer_ops->disable_vblank)
return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
}
@@ -200,8 +185,6 @@ static void drm_hdmi_wait_for_vblank(struct device *subdrv_dev)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (mixer_ops && mixer_ops->wait_for_vblank)
mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
}
@@ -214,11 +197,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
struct drm_display_mode *m;
int mode_ok;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
drm_mode_set_crtcinfo(adjusted_mode, 0);
- mode_ok = drm_hdmi_check_timing(subdrv_dev, adjusted_mode);
+ mode_ok = drm_hdmi_check_mode(subdrv_dev, adjusted_mode);
/* just return if user desired mode exists. */
if (mode_ok == 0)
@@ -229,7 +210,7 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
* to adjusted_mode.
*/
list_for_each_entry(m, &connector->modes, head) {
- mode_ok = drm_hdmi_check_timing(subdrv_dev, m);
+ mode_ok = drm_hdmi_check_mode(subdrv_dev, m);
if (mode_ok == 0) {
struct drm_mode_object base;
@@ -256,8 +237,6 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (hdmi_ops && hdmi_ops->mode_set)
hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
}
@@ -267,8 +246,6 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (hdmi_ops && hdmi_ops->get_max_resol)
hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
}
@@ -277,8 +254,6 @@ static void drm_hdmi_commit(struct device *subdrv_dev)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (hdmi_ops && hdmi_ops->commit)
hdmi_ops->commit(ctx->hdmi_ctx->ctx);
}
@@ -287,8 +262,6 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (mixer_ops && mixer_ops->dpms)
mixer_ops->dpms(ctx->mixer_ctx->ctx, mode);
@@ -301,8 +274,6 @@ static void drm_hdmi_apply(struct device *subdrv_dev)
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
int i;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
for (i = 0; i < MIXER_WIN_NR; i++) {
if (!ctx->enabled[i])
continue;
@@ -331,8 +302,6 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (mixer_ops && mixer_ops->win_mode_set)
mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
}
@@ -342,9 +311,7 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
- if (win < 0 || win > MIXER_WIN_NR) {
+ if (win < 0 || win >= MIXER_WIN_NR) {
DRM_ERROR("mixer window[%d] is wrong\n", win);
return;
}
@@ -360,9 +327,7 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
- if (win < 0 || win > MIXER_WIN_NR) {
+ if (win < 0 || win >= MIXER_WIN_NR) {
DRM_ERROR("mixer window[%d] is wrong\n", win);
return;
}
@@ -392,8 +357,6 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
struct drm_hdmi_context *ctx;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (!hdmi_ctx) {
DRM_ERROR("hdmi context not initialized.\n");
return -EFAULT;
@@ -440,8 +403,6 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev)
struct exynos_drm_subdrv *subdrv;
struct drm_hdmi_context *ctx;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
DRM_LOG_KMS("failed to alloc common hdmi context.\n");
@@ -466,8 +427,6 @@ static int exynos_drm_hdmi_remove(struct platform_device *pdev)
{
struct drm_hdmi_context *ctx = platform_get_drvdata(pdev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_drm_subdrv_unregister(&ctx->subdrv);
return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index 6b709440df4c..724cab181976 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -32,11 +32,11 @@ struct exynos_hdmi_ops {
bool (*is_connected)(void *ctx);
struct edid *(*get_edid)(void *ctx,
struct drm_connector *connector);
- int (*check_timing)(void *ctx, struct fb_videomode *timing);
+ int (*check_mode)(void *ctx, struct drm_display_mode *mode);
int (*power_on)(void *ctx, int mode);
/* manager */
- void (*mode_set)(void *ctx, void *mode);
+ void (*mode_set)(void *ctx, struct drm_display_mode *mode);
void (*get_max_resol)(void *ctx, unsigned int *width,
unsigned int *height);
void (*commit)(void *ctx);
@@ -57,7 +57,7 @@ struct exynos_mixer_ops {
void (*win_disable)(void *ctx, int zpos);
/* display */
- int (*check_timing)(void *ctx, struct fb_videomode *timing);
+ int (*check_mode)(void *ctx, struct drm_display_mode *mode);
};
void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index be1e88463466..b1ef8e7ff9c9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -131,8 +131,6 @@ void exynos_platform_device_ipp_unregister(void)
int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
{
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!ippdrv)
return -EINVAL;
@@ -145,8 +143,6 @@ int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
{
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!ippdrv)
return -EINVAL;
@@ -162,8 +158,6 @@ static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj,
{
int ret;
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* do the allocation under our mutexlock */
mutex_lock(lock);
ret = idr_alloc(id_idr, obj, 1, 0, GFP_KERNEL);
@@ -179,7 +173,7 @@ static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id)
{
void *obj;
- DRM_DEBUG_KMS("%s:id[%d]\n", __func__, id);
+ DRM_DEBUG_KMS("id[%d]\n", id);
mutex_lock(lock);
@@ -216,7 +210,7 @@ static struct exynos_drm_ippdrv *ipp_find_driver(struct ipp_context *ctx,
struct exynos_drm_ippdrv *ippdrv;
u32 ipp_id = property->ipp_id;
- DRM_DEBUG_KMS("%s:ipp_id[%d]\n", __func__, ipp_id);
+ DRM_DEBUG_KMS("ipp_id[%d]\n", ipp_id);
if (ipp_id) {
/* find ipp driver using idr */
@@ -257,14 +251,13 @@ static struct exynos_drm_ippdrv *ipp_find_driver(struct ipp_context *ctx,
*/
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
if (ipp_check_dedicated(ippdrv, property->cmd)) {
- DRM_DEBUG_KMS("%s:used device.\n", __func__);
+ DRM_DEBUG_KMS("used device.\n");
continue;
}
if (ippdrv->check_property &&
ippdrv->check_property(ippdrv->dev, property)) {
- DRM_DEBUG_KMS("%s:not support property.\n",
- __func__);
+ DRM_DEBUG_KMS("not support property.\n");
continue;
}
@@ -283,10 +276,10 @@ static struct exynos_drm_ippdrv *ipp_find_drv_by_handle(u32 prop_id)
struct drm_exynos_ipp_cmd_node *c_node;
int count = 0;
- DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, prop_id);
+ DRM_DEBUG_KMS("prop_id[%d]\n", prop_id);
if (list_empty(&exynos_drm_ippdrv_list)) {
- DRM_DEBUG_KMS("%s:ippdrv_list is empty.\n", __func__);
+ DRM_DEBUG_KMS("ippdrv_list is empty.\n");
return ERR_PTR(-ENODEV);
}
@@ -296,8 +289,7 @@ static struct exynos_drm_ippdrv *ipp_find_drv_by_handle(u32 prop_id)
* e.g PAUSE state, queue buf, command contro.
*/
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
- DRM_DEBUG_KMS("%s:count[%d]ippdrv[0x%x]\n", __func__,
- count++, (int)ippdrv);
+ DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv);
if (!list_empty(&ippdrv->cmd_list)) {
list_for_each_entry(c_node, &ippdrv->cmd_list, list)
@@ -320,8 +312,6 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
struct exynos_drm_ippdrv *ippdrv;
int count = 0;
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!ctx) {
DRM_ERROR("invalid context.\n");
return -EINVAL;
@@ -332,7 +322,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
return -EINVAL;
}
- DRM_DEBUG_KMS("%s:ipp_id[%d]\n", __func__, prop_list->ipp_id);
+ DRM_DEBUG_KMS("ipp_id[%d]\n", prop_list->ipp_id);
if (!prop_list->ipp_id) {
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list)
@@ -371,11 +361,11 @@ static void ipp_print_property(struct drm_exynos_ipp_property *property,
struct drm_exynos_pos *pos = &config->pos;
struct drm_exynos_sz *sz = &config->sz;
- DRM_DEBUG_KMS("%s:prop_id[%d]ops[%s]fmt[0x%x]\n",
- __func__, property->prop_id, idx ? "dst" : "src", config->fmt);
+ DRM_DEBUG_KMS("prop_id[%d]ops[%s]fmt[0x%x]\n",
+ property->prop_id, idx ? "dst" : "src", config->fmt);
- DRM_DEBUG_KMS("%s:pos[%d %d %d %d]sz[%d %d]f[%d]r[%d]\n",
- __func__, pos->x, pos->y, pos->w, pos->h,
+ DRM_DEBUG_KMS("pos[%d %d %d %d]sz[%d %d]f[%d]r[%d]\n",
+ pos->x, pos->y, pos->w, pos->h,
sz->hsize, sz->vsize, config->flip, config->degree);
}
@@ -385,7 +375,7 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property)
struct drm_exynos_ipp_cmd_node *c_node;
u32 prop_id = property->prop_id;
- DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, prop_id);
+ DRM_DEBUG_KMS("prop_id[%d]\n", prop_id);
ippdrv = ipp_find_drv_by_handle(prop_id);
if (IS_ERR(ippdrv)) {
@@ -401,8 +391,8 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property)
list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
if ((c_node->property.prop_id == prop_id) &&
(c_node->state == IPP_STATE_STOP)) {
- DRM_DEBUG_KMS("%s:found cmd[%d]ippdrv[0x%x]\n",
- __func__, property->cmd, (int)ippdrv);
+ DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n",
+ property->cmd, (int)ippdrv);
c_node->property = *property;
return 0;
@@ -418,8 +408,6 @@ static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void)
{
struct drm_exynos_ipp_cmd_work *cmd_work;
- DRM_DEBUG_KMS("%s\n", __func__);
-
cmd_work = kzalloc(sizeof(*cmd_work), GFP_KERNEL);
if (!cmd_work) {
DRM_ERROR("failed to alloc cmd_work.\n");
@@ -435,8 +423,6 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void)
{
struct drm_exynos_ipp_event_work *event_work;
- DRM_DEBUG_KMS("%s\n", __func__);
-
event_work = kzalloc(sizeof(*event_work), GFP_KERNEL);
if (!event_work) {
DRM_ERROR("failed to alloc event_work.\n");
@@ -460,8 +446,6 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
struct drm_exynos_ipp_cmd_node *c_node;
int ret, i;
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!ctx) {
DRM_ERROR("invalid context.\n");
return -EINVAL;
@@ -486,7 +470,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
* instead of allocation.
*/
if (property->prop_id) {
- DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+ DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
return ipp_find_and_set_property(property);
}
@@ -512,8 +496,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
goto err_clear;
}
- DRM_DEBUG_KMS("%s:created prop_id[%d]cmd[%d]ippdrv[0x%x]\n",
- __func__, property->prop_id, property->cmd, (int)ippdrv);
+ DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[0x%x]\n",
+ property->prop_id, property->cmd, (int)ippdrv);
/* stored property information and ippdrv in private data */
c_node->priv = priv;
@@ -569,8 +553,6 @@ err_clear:
static void ipp_clean_cmd_node(struct drm_exynos_ipp_cmd_node *c_node)
{
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* delete list */
list_del(&c_node->list);
@@ -593,8 +575,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
struct list_head *head;
int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, };
- DRM_DEBUG_KMS("%s\n", __func__);
-
mutex_lock(&c_node->mem_lock);
for_each_ipp_ops(i) {
@@ -602,20 +582,19 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
head = &c_node->mem_list[i];
if (list_empty(head)) {
- DRM_DEBUG_KMS("%s:%s memory empty.\n", __func__,
- i ? "dst" : "src");
+ DRM_DEBUG_KMS("%s memory empty.\n", i ? "dst" : "src");
continue;
}
/* find memory node entry */
list_for_each_entry(m_node, head, list) {
- DRM_DEBUG_KMS("%s:%s,count[%d]m_node[0x%x]\n", __func__,
+ DRM_DEBUG_KMS("%s,count[%d]m_node[0x%x]\n",
i ? "dst" : "src", count[i], (int)m_node);
count[i]++;
}
}
- DRM_DEBUG_KMS("%s:min[%d]max[%d]\n", __func__,
+ DRM_DEBUG_KMS("min[%d]max[%d]\n",
min(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]),
max(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]));
@@ -644,15 +623,14 @@ static struct drm_exynos_ipp_mem_node
struct list_head *head;
int count = 0;
- DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, qbuf->buf_id);
+ DRM_DEBUG_KMS("buf_id[%d]\n", qbuf->buf_id);
/* source/destination memory list */
head = &c_node->mem_list[qbuf->ops_id];
/* find memory node from memory list */
list_for_each_entry(m_node, head, list) {
- DRM_DEBUG_KMS("%s:count[%d]m_node[0x%x]\n",
- __func__, count++, (int)m_node);
+ DRM_DEBUG_KMS("count[%d]m_node[0x%x]\n", count++, (int)m_node);
/* compare buffer id */
if (m_node->buf_id == qbuf->buf_id)
@@ -669,7 +647,7 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
struct exynos_drm_ipp_ops *ops = NULL;
int ret = 0;
- DRM_DEBUG_KMS("%s:node[0x%x]\n", __func__, (int)m_node);
+ DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
if (!m_node) {
DRM_ERROR("invalid queue node.\n");
@@ -678,7 +656,7 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
mutex_lock(&c_node->mem_lock);
- DRM_DEBUG_KMS("%s:ops_id[%d]\n", __func__, m_node->ops_id);
+ DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
/* get operations callback */
ops = ippdrv->ops[m_node->ops_id];
@@ -714,8 +692,6 @@ static struct drm_exynos_ipp_mem_node
void *addr;
int i;
- DRM_DEBUG_KMS("%s\n", __func__);
-
mutex_lock(&c_node->mem_lock);
m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
@@ -732,14 +708,11 @@ static struct drm_exynos_ipp_mem_node
m_node->prop_id = qbuf->prop_id;
m_node->buf_id = qbuf->buf_id;
- DRM_DEBUG_KMS("%s:m_node[0x%x]ops_id[%d]\n", __func__,
- (int)m_node, qbuf->ops_id);
- DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]\n", __func__,
- qbuf->prop_id, m_node->buf_id);
+ DRM_DEBUG_KMS("m_node[0x%x]ops_id[%d]\n", (int)m_node, qbuf->ops_id);
+ DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]\n", qbuf->prop_id, m_node->buf_id);
for_each_ipp_planar(i) {
- DRM_DEBUG_KMS("%s:i[%d]handle[0x%x]\n", __func__,
- i, qbuf->handle[i]);
+ DRM_DEBUG_KMS("i[%d]handle[0x%x]\n", i, qbuf->handle[i]);
/* get dma address by handle */
if (qbuf->handle[i]) {
@@ -752,9 +725,8 @@ static struct drm_exynos_ipp_mem_node
buf_info.handles[i] = qbuf->handle[i];
buf_info.base[i] = *(dma_addr_t *) addr;
- DRM_DEBUG_KMS("%s:i[%d]base[0x%x]hd[0x%x]\n",
- __func__, i, buf_info.base[i],
- (int)buf_info.handles[i]);
+ DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%x]\n",
+ i, buf_info.base[i], (int)buf_info.handles[i]);
}
}
@@ -778,7 +750,7 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
{
int i;
- DRM_DEBUG_KMS("%s:node[0x%x]\n", __func__, (int)m_node);
+ DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
if (!m_node) {
DRM_ERROR("invalid dequeue node.\n");
@@ -792,7 +764,7 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
mutex_lock(&c_node->mem_lock);
- DRM_DEBUG_KMS("%s:ops_id[%d]\n", __func__, m_node->ops_id);
+ DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
/* put gem buffer */
for_each_ipp_planar(i) {
@@ -824,8 +796,7 @@ static int ipp_get_event(struct drm_device *drm_dev,
struct drm_exynos_ipp_send_event *e;
unsigned long flags;
- DRM_DEBUG_KMS("%s:ops_id[%d]buf_id[%d]\n", __func__,
- qbuf->ops_id, qbuf->buf_id);
+ DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id);
e = kzalloc(sizeof(*e), GFP_KERNEL);
@@ -857,16 +828,13 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,
struct drm_exynos_ipp_send_event *e, *te;
int count = 0;
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (list_empty(&c_node->event_list)) {
- DRM_DEBUG_KMS("%s:event_list is empty.\n", __func__);
+ DRM_DEBUG_KMS("event_list is empty.\n");
return;
}
list_for_each_entry_safe(e, te, &c_node->event_list, base.link) {
- DRM_DEBUG_KMS("%s:count[%d]e[0x%x]\n",
- __func__, count++, (int)e);
+ DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e);
/*
* quf == NULL condition means all event deletion.
@@ -912,8 +880,6 @@ static int ipp_queue_buf_with_run(struct device *dev,
struct exynos_drm_ipp_ops *ops;
int ret;
- DRM_DEBUG_KMS("%s\n", __func__);
-
ippdrv = ipp_find_drv_by_handle(qbuf->prop_id);
if (IS_ERR(ippdrv)) {
DRM_ERROR("failed to get ipp driver.\n");
@@ -929,12 +895,12 @@ static int ipp_queue_buf_with_run(struct device *dev,
property = &c_node->property;
if (c_node->state != IPP_STATE_START) {
- DRM_DEBUG_KMS("%s:bypass for invalid state.\n" , __func__);
+ DRM_DEBUG_KMS("bypass for invalid state.\n");
return 0;
}
if (!ipp_check_mem_list(c_node)) {
- DRM_DEBUG_KMS("%s:empty memory.\n", __func__);
+ DRM_DEBUG_KMS("empty memory.\n");
return 0;
}
@@ -964,8 +930,6 @@ static void ipp_clean_queue_buf(struct drm_device *drm_dev,
{
struct drm_exynos_ipp_mem_node *m_node, *tm_node;
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!list_empty(&c_node->mem_list[qbuf->ops_id])) {
/* delete list */
list_for_each_entry_safe(m_node, tm_node,
@@ -989,8 +953,6 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
struct drm_exynos_ipp_mem_node *m_node;
int ret;
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!qbuf) {
DRM_ERROR("invalid buf parameter.\n");
return -EINVAL;
@@ -1001,8 +963,8 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
return -EINVAL;
}
- DRM_DEBUG_KMS("%s:prop_id[%d]ops_id[%s]buf_id[%d]buf_type[%d]\n",
- __func__, qbuf->prop_id, qbuf->ops_id ? "dst" : "src",
+ DRM_DEBUG_KMS("prop_id[%d]ops_id[%s]buf_id[%d]buf_type[%d]\n",
+ qbuf->prop_id, qbuf->ops_id ? "dst" : "src",
qbuf->buf_id, qbuf->buf_type);
/* find command node */
@@ -1075,8 +1037,6 @@ err_clean_node:
static bool exynos_drm_ipp_check_valid(struct device *dev,
enum drm_exynos_ipp_ctrl ctrl, enum drm_exynos_ipp_state state)
{
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (ctrl != IPP_CTRL_PLAY) {
if (pm_runtime_suspended(dev)) {
DRM_ERROR("pm:runtime_suspended.\n");
@@ -1104,7 +1064,6 @@ static bool exynos_drm_ipp_check_valid(struct device *dev,
default:
DRM_ERROR("invalid state.\n");
goto err_status;
- break;
}
return true;
@@ -1126,8 +1085,6 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
struct drm_exynos_ipp_cmd_work *cmd_work;
struct drm_exynos_ipp_cmd_node *c_node;
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!ctx) {
DRM_ERROR("invalid context.\n");
return -EINVAL;
@@ -1138,7 +1095,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
return -EINVAL;
}
- DRM_DEBUG_KMS("%s:ctrl[%d]prop_id[%d]\n", __func__,
+ DRM_DEBUG_KMS("ctrl[%d]prop_id[%d]\n",
cmd_ctrl->ctrl, cmd_ctrl->prop_id);
ippdrv = ipp_find_drv_by_handle(cmd_ctrl->prop_id);
@@ -1213,7 +1170,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
return -EINVAL;
}
- DRM_DEBUG_KMS("%s:done ctrl[%d]prop_id[%d]\n", __func__,
+ DRM_DEBUG_KMS("done ctrl[%d]prop_id[%d]\n",
cmd_ctrl->ctrl, cmd_ctrl->prop_id);
return 0;
@@ -1249,7 +1206,7 @@ static int ipp_set_property(struct exynos_drm_ippdrv *ippdrv,
return -EINVAL;
}
- DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+ DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
/* reset h/w block */
if (ippdrv->reset &&
@@ -1310,13 +1267,13 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
struct list_head *head;
int ret, i;
- DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+ DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
/* store command info in ippdrv */
ippdrv->c_node = c_node;
if (!ipp_check_mem_list(c_node)) {
- DRM_DEBUG_KMS("%s:empty memory.\n", __func__);
+ DRM_DEBUG_KMS("empty memory.\n");
return -ENOMEM;
}
@@ -1343,8 +1300,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
return ret;
}
- DRM_DEBUG_KMS("%s:m_node[0x%x]\n",
- __func__, (int)m_node);
+ DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node);
ret = ipp_set_mem_node(ippdrv, c_node, m_node);
if (ret) {
@@ -1382,7 +1338,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
return -EINVAL;
}
- DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, property->cmd);
+ DRM_DEBUG_KMS("cmd[%d]\n", property->cmd);
/* start operations */
if (ippdrv->start) {
@@ -1405,7 +1361,7 @@ static int ipp_stop_property(struct drm_device *drm_dev,
struct list_head *head;
int ret = 0, i;
- DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+ DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
/* put event */
ipp_put_event(c_node, NULL);
@@ -1418,8 +1374,7 @@ static int ipp_stop_property(struct drm_device *drm_dev,
head = &c_node->mem_list[i];
if (list_empty(head)) {
- DRM_DEBUG_KMS("%s:mem_list is empty.\n",
- __func__);
+ DRM_DEBUG_KMS("mem_list is empty.\n");
break;
}
@@ -1439,7 +1394,7 @@ static int ipp_stop_property(struct drm_device *drm_dev,
head = &c_node->mem_list[EXYNOS_DRM_OPS_DST];
if (list_empty(head)) {
- DRM_DEBUG_KMS("%s:mem_list is empty.\n", __func__);
+ DRM_DEBUG_KMS("mem_list is empty.\n");
break;
}
@@ -1456,7 +1411,7 @@ static int ipp_stop_property(struct drm_device *drm_dev,
head = &c_node->mem_list[EXYNOS_DRM_OPS_SRC];
if (list_empty(head)) {
- DRM_DEBUG_KMS("%s:mem_list is empty.\n", __func__);
+ DRM_DEBUG_KMS("mem_list is empty.\n");
break;
}
@@ -1491,8 +1446,6 @@ void ipp_sched_cmd(struct work_struct *work)
struct drm_exynos_ipp_property *property;
int ret;
- DRM_DEBUG_KMS("%s\n", __func__);
-
ippdrv = cmd_work->ippdrv;
if (!ippdrv) {
DRM_ERROR("invalid ippdrv list.\n");
@@ -1550,7 +1503,7 @@ void ipp_sched_cmd(struct work_struct *work)
break;
}
- DRM_DEBUG_KMS("%s:ctrl[%d] done.\n", __func__, cmd_work->ctrl);
+ DRM_DEBUG_KMS("ctrl[%d] done.\n", cmd_work->ctrl);
err_unlock:
mutex_unlock(&c_node->cmd_lock);
@@ -1571,8 +1524,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
int ret, i;
for_each_ipp_ops(i)
- DRM_DEBUG_KMS("%s:%s buf_id[%d]\n", __func__,
- i ? "dst" : "src", buf_id[i]);
+ DRM_DEBUG_KMS("%s buf_id[%d]\n", i ? "dst" : "src", buf_id[i]);
if (!drm_dev) {
DRM_ERROR("failed to get drm_dev.\n");
@@ -1585,12 +1537,12 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
}
if (list_empty(&c_node->event_list)) {
- DRM_DEBUG_KMS("%s:event list is empty.\n", __func__);
+ DRM_DEBUG_KMS("event list is empty.\n");
return 0;
}
if (!ipp_check_mem_list(c_node)) {
- DRM_DEBUG_KMS("%s:empty memory.\n", __func__);
+ DRM_DEBUG_KMS("empty memory.\n");
return 0;
}
@@ -1609,7 +1561,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
}
tbuf_id[i] = m_node->buf_id;
- DRM_DEBUG_KMS("%s:%s buf_id[%d]\n", __func__,
+ DRM_DEBUG_KMS("%s buf_id[%d]\n",
i ? "dst" : "src", tbuf_id[i]);
ret = ipp_put_mem_node(drm_dev, c_node, m_node);
@@ -1677,8 +1629,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
}
do_gettimeofday(&now);
- DRM_DEBUG_KMS("%s:tv_sec[%ld]tv_usec[%ld]\n"
- , __func__, now.tv_sec, now.tv_usec);
+ DRM_DEBUG_KMS("tv_sec[%ld]tv_usec[%ld]\n", now.tv_sec, now.tv_usec);
e->event.tv_sec = now.tv_sec;
e->event.tv_usec = now.tv_usec;
e->event.prop_id = property->prop_id;
@@ -1692,7 +1643,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
wake_up_interruptible(&e->base.file_priv->event_wait);
spin_unlock_irqrestore(&drm_dev->event_lock, flags);
- DRM_DEBUG_KMS("%s:done cmd[%d]prop_id[%d]buf_id[%d]\n", __func__,
+ DRM_DEBUG_KMS("done cmd[%d]prop_id[%d]buf_id[%d]\n",
property->cmd, property->prop_id, tbuf_id[EXYNOS_DRM_OPS_DST]);
return 0;
@@ -1711,8 +1662,7 @@ void ipp_sched_event(struct work_struct *work)
return;
}
- DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__,
- event_work->buf_id[EXYNOS_DRM_OPS_DST]);
+ DRM_DEBUG_KMS("buf_id[%d]\n", event_work->buf_id[EXYNOS_DRM_OPS_DST]);
ippdrv = event_work->ippdrv;
if (!ippdrv) {
@@ -1733,8 +1683,8 @@ void ipp_sched_event(struct work_struct *work)
* or going out operations.
*/
if (c_node->state != IPP_STATE_START) {
- DRM_DEBUG_KMS("%s:bypass state[%d]prop_id[%d]\n",
- __func__, c_node->state, c_node->property.prop_id);
+ DRM_DEBUG_KMS("bypass state[%d]prop_id[%d]\n",
+ c_node->state, c_node->property.prop_id);
goto err_completion;
}
@@ -1759,8 +1709,6 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
struct exynos_drm_ippdrv *ippdrv;
int ret, count = 0;
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* get ipp driver entry */
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
ippdrv->drm_dev = drm_dev;
@@ -1772,7 +1720,7 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
goto err_idr;
}
- DRM_DEBUG_KMS("%s:count[%d]ippdrv[0x%x]ipp_id[%d]\n", __func__,
+ DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n",
count++, (int)ippdrv, ippdrv->ipp_id);
if (ippdrv->ipp_id == 0) {
@@ -1816,8 +1764,6 @@ static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
{
struct exynos_drm_ippdrv *ippdrv;
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* get ipp driver entry */
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
if (is_drm_iommu_supported(drm_dev))
@@ -1834,8 +1780,6 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev,
struct drm_exynos_file_private *file_priv = file->driver_priv;
struct exynos_drm_ipp_private *priv;
- DRM_DEBUG_KMS("%s\n", __func__);
-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
DRM_ERROR("failed to allocate priv.\n");
@@ -1846,7 +1790,7 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev,
INIT_LIST_HEAD(&priv->event_list);
- DRM_DEBUG_KMS("%s:done priv[0x%x]\n", __func__, (int)priv);
+ DRM_DEBUG_KMS("done priv[0x%x]\n", (int)priv);
return 0;
}
@@ -1860,10 +1804,10 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
struct drm_exynos_ipp_cmd_node *c_node, *tc_node;
int count = 0;
- DRM_DEBUG_KMS("%s:for priv[0x%x]\n", __func__, (int)priv);
+ DRM_DEBUG_KMS("for priv[0x%x]\n", (int)priv);
if (list_empty(&exynos_drm_ippdrv_list)) {
- DRM_DEBUG_KMS("%s:ippdrv_list is empty.\n", __func__);
+ DRM_DEBUG_KMS("ippdrv_list is empty.\n");
goto err_clear;
}
@@ -1873,8 +1817,8 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
list_for_each_entry_safe(c_node, tc_node,
&ippdrv->cmd_list, list) {
- DRM_DEBUG_KMS("%s:count[%d]ippdrv[0x%x]\n",
- __func__, count++, (int)ippdrv);
+ DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n",
+ count++, (int)ippdrv);
if (c_node->priv == priv) {
/*
@@ -1913,8 +1857,6 @@ static int ipp_probe(struct platform_device *pdev)
if (!ctx)
return -ENOMEM;
- DRM_DEBUG_KMS("%s\n", __func__);
-
mutex_init(&ctx->ipp_lock);
mutex_init(&ctx->prop_lock);
@@ -1978,8 +1920,6 @@ static int ipp_remove(struct platform_device *pdev)
{
struct ipp_context *ctx = platform_get_drvdata(pdev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
/* unregister sub driver */
exynos_drm_subdrv_unregister(&ctx->subdrv);
@@ -1999,7 +1939,7 @@ static int ipp_remove(struct platform_device *pdev)
static int ipp_power_ctrl(struct ipp_context *ctx, bool enable)
{
- DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+ DRM_DEBUG_KMS("enable[%d]\n", enable);
return 0;
}
@@ -2009,8 +1949,6 @@ static int ipp_suspend(struct device *dev)
{
struct ipp_context *ctx = get_ipp_context(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (pm_runtime_suspended(dev))
return 0;
@@ -2021,8 +1959,6 @@ static int ipp_resume(struct device *dev)
{
struct ipp_context *ctx = get_ipp_context(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!pm_runtime_suspended(dev))
return ipp_power_ctrl(ctx, true);
@@ -2035,8 +1971,6 @@ static int ipp_runtime_suspend(struct device *dev)
{
struct ipp_context *ctx = get_ipp_context(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
return ipp_power_ctrl(ctx, false);
}
@@ -2044,8 +1978,6 @@ static int ipp_runtime_resume(struct device *dev)
{
struct ipp_context *ctx = get_ipp_context(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
return ipp_power_ctrl(ctx, true);
}
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 83efc662d65a..6ee55e68e0a2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -81,8 +81,6 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
int nr;
int i;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
nr = exynos_drm_fb_get_buf_cnt(fb);
for (i = 0; i < nr; i++) {
struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
@@ -159,8 +157,6 @@ void exynos_plane_dpms(struct drm_plane *plane, int mode)
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (mode == DRM_MODE_DPMS_ON) {
if (exynos_plane->enabled)
return;
@@ -189,8 +185,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
{
int ret;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
crtc_w, crtc_h, src_x >> 16, src_y >> 16,
src_w >> 16, src_h >> 16);
@@ -207,8 +201,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
static int exynos_disable_plane(struct drm_plane *plane)
{
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
exynos_plane_dpms(plane, DRM_MODE_DPMS_OFF);
return 0;
@@ -218,8 +210,6 @@ static void exynos_plane_destroy(struct drm_plane *plane)
{
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
exynos_disable_plane(plane);
drm_plane_cleanup(plane);
kfree(exynos_plane);
@@ -233,8 +223,6 @@ static int exynos_plane_set_property(struct drm_plane *plane,
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_private *dev_priv = dev->dev_private;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (property == dev_priv->plane_zpos_property) {
exynos_plane->overlay.zpos = val;
return 0;
@@ -256,8 +244,6 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane)
struct exynos_drm_private *dev_priv = dev->dev_private;
struct drm_property *prop;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
prop = dev_priv->plane_zpos_property;
if (!prop) {
prop = drm_property_create_range(dev, 0, "zpos", 0,
@@ -277,8 +263,6 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
struct exynos_plane *exynos_plane;
int err;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
if (!exynos_plane) {
DRM_ERROR("failed to allocate plane\n");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index 9b6c70964d71..427640aa5148 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -244,7 +244,7 @@ static int rotator_src_set_size(struct device *dev, int swap,
/* Get format */
fmt = rotator_reg_get_fmt(rot);
if (!rotator_check_reg_fmt(fmt)) {
- DRM_ERROR("%s:invalid format.\n", __func__);
+ DRM_ERROR("invalid format.\n");
return -EINVAL;
}
@@ -287,7 +287,7 @@ static int rotator_src_set_addr(struct device *dev,
/* Get format */
fmt = rotator_reg_get_fmt(rot);
if (!rotator_check_reg_fmt(fmt)) {
- DRM_ERROR("%s:invalid format.\n", __func__);
+ DRM_ERROR("invalid format.\n");
return -EINVAL;
}
@@ -381,7 +381,7 @@ static int rotator_dst_set_size(struct device *dev, int swap,
/* Get format */
fmt = rotator_reg_get_fmt(rot);
if (!rotator_check_reg_fmt(fmt)) {
- DRM_ERROR("%s:invalid format.\n", __func__);
+ DRM_ERROR("invalid format.\n");
return -EINVAL;
}
@@ -422,7 +422,7 @@ static int rotator_dst_set_addr(struct device *dev,
/* Get format */
fmt = rotator_reg_get_fmt(rot);
if (!rotator_check_reg_fmt(fmt)) {
- DRM_ERROR("%s:invalid format.\n", __func__);
+ DRM_ERROR("invalid format.\n");
return -EINVAL;
}
@@ -471,8 +471,6 @@ static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
{
struct drm_exynos_ipp_prop_list *prop_list;
- DRM_DEBUG_KMS("%s\n", __func__);
-
prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
if (!prop_list) {
DRM_ERROR("failed to alloc property list.\n");
@@ -502,7 +500,7 @@ static inline bool rotator_check_drm_fmt(u32 fmt)
case DRM_FORMAT_NV12:
return true;
default:
- DRM_DEBUG_KMS("%s:not support format\n", __func__);
+ DRM_DEBUG_KMS("not support format\n");
return false;
}
}
@@ -516,7 +514,7 @@ static inline bool rotator_check_drm_flip(enum drm_exynos_flip flip)
case EXYNOS_DRM_FLIP_BOTH:
return true;
default:
- DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+ DRM_DEBUG_KMS("invalid flip\n");
return false;
}
}
@@ -536,19 +534,18 @@ static int rotator_ippdrv_check_property(struct device *dev,
/* Check format configuration */
if (src_config->fmt != dst_config->fmt) {
- DRM_DEBUG_KMS("%s:not support csc feature\n", __func__);
+ DRM_DEBUG_KMS("not support csc feature\n");
return -EINVAL;
}
if (!rotator_check_drm_fmt(dst_config->fmt)) {
- DRM_DEBUG_KMS("%s:invalid format\n", __func__);
+ DRM_DEBUG_KMS("invalid format\n");
return -EINVAL;
}
/* Check transform configuration */
if (src_config->degree != EXYNOS_DRM_DEGREE_0) {
- DRM_DEBUG_KMS("%s:not support source-side rotation\n",
- __func__);
+ DRM_DEBUG_KMS("not support source-side rotation\n");
return -EINVAL;
}
@@ -561,51 +558,47 @@ static int rotator_ippdrv_check_property(struct device *dev,
/* No problem */
break;
default:
- DRM_DEBUG_KMS("%s:invalid degree\n", __func__);
+ DRM_DEBUG_KMS("invalid degree\n");
return -EINVAL;
}
if (src_config->flip != EXYNOS_DRM_FLIP_NONE) {
- DRM_DEBUG_KMS("%s:not support source-side flip\n", __func__);
+ DRM_DEBUG_KMS("not support source-side flip\n");
return -EINVAL;
}
if (!rotator_check_drm_flip(dst_config->flip)) {
- DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+ DRM_DEBUG_KMS("invalid flip\n");
return -EINVAL;
}
/* Check size configuration */
if ((src_pos->x + src_pos->w > src_sz->hsize) ||
(src_pos->y + src_pos->h > src_sz->vsize)) {
- DRM_DEBUG_KMS("%s:out of source buffer bound\n", __func__);
+ DRM_DEBUG_KMS("out of source buffer bound\n");
return -EINVAL;
}
if (swap) {
if ((dst_pos->x + dst_pos->h > dst_sz->vsize) ||
(dst_pos->y + dst_pos->w > dst_sz->hsize)) {
- DRM_DEBUG_KMS("%s:out of destination buffer bound\n",
- __func__);
+ DRM_DEBUG_KMS("out of destination buffer bound\n");
return -EINVAL;
}
if ((src_pos->w != dst_pos->h) || (src_pos->h != dst_pos->w)) {
- DRM_DEBUG_KMS("%s:not support scale feature\n",
- __func__);
+ DRM_DEBUG_KMS("not support scale feature\n");
return -EINVAL;
}
} else {
if ((dst_pos->x + dst_pos->w > dst_sz->hsize) ||
(dst_pos->y + dst_pos->h > dst_sz->vsize)) {
- DRM_DEBUG_KMS("%s:out of destination buffer bound\n",
- __func__);
+ DRM_DEBUG_KMS("out of destination buffer bound\n");
return -EINVAL;
}
if ((src_pos->w != dst_pos->w) || (src_pos->h != dst_pos->h)) {
- DRM_DEBUG_KMS("%s:not support scale feature\n",
- __func__);
+ DRM_DEBUG_KMS("not support scale feature\n");
return -EINVAL;
}
}
@@ -693,7 +686,7 @@ static int rotator_probe(struct platform_device *pdev)
goto err_ippdrv_register;
}
- DRM_DEBUG_KMS("%s:ippdrv[0x%x]\n", __func__, (int)ippdrv);
+ DRM_DEBUG_KMS("ippdrv[0x%x]\n", (int)ippdrv);
platform_set_drvdata(pdev, rot);
@@ -752,8 +745,6 @@ static struct platform_device_id rotator_driver_ids[] = {
static int rotator_clk_crtl(struct rot_context *rot, bool enable)
{
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (enable) {
clk_enable(rot->clock);
rot->suspended = false;
@@ -771,8 +762,6 @@ static int rotator_suspend(struct device *dev)
{
struct rot_context *rot = dev_get_drvdata(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (pm_runtime_suspended(dev))
return 0;
@@ -783,8 +772,6 @@ static int rotator_resume(struct device *dev)
{
struct rot_context *rot = dev_get_drvdata(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
if (!pm_runtime_suspended(dev))
return rotator_clk_crtl(rot, true);
@@ -797,8 +784,6 @@ static int rotator_runtime_suspend(struct device *dev)
{
struct rot_context *rot = dev_get_drvdata(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
return rotator_clk_crtl(rot, false);
}
@@ -806,8 +791,6 @@ static int rotator_runtime_resume(struct device *dev)
{
struct rot_context *rot = dev_get_drvdata(dev);
- DRM_DEBUG_KMS("%s\n", __func__);
-
return rotator_clk_crtl(rot, true);
}
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 24376c194a5e..784bbce0741a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -89,8 +89,6 @@ static bool vidi_display_is_connected(struct device *dev)
{
struct vidi_context *ctx = get_vidi_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* connection request would come from user side
* to do hotplug through specific ioctl.
@@ -105,8 +103,6 @@ static struct edid *vidi_get_edid(struct device *dev,
struct edid *edid;
int edid_len;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* the edid data comes from user side and it would be set
* to ctx->raw_edid through specific ioctl.
@@ -128,17 +124,13 @@ static struct edid *vidi_get_edid(struct device *dev,
static void *vidi_get_panel(struct device *dev)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO. */
return NULL;
}
-static int vidi_check_timing(struct device *dev, void *timing)
+static int vidi_check_mode(struct device *dev, struct drm_display_mode *mode)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO. */
return 0;
@@ -146,8 +138,6 @@ static int vidi_check_timing(struct device *dev, void *timing)
static int vidi_display_power_on(struct device *dev, int mode)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO */
return 0;
@@ -158,7 +148,7 @@ static struct exynos_drm_display_ops vidi_display_ops = {
.is_connected = vidi_display_is_connected,
.get_edid = vidi_get_edid,
.get_panel = vidi_get_panel,
- .check_timing = vidi_check_timing,
+ .check_mode = vidi_check_mode,
.power_on = vidi_display_power_on,
};
@@ -166,7 +156,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode)
{
struct vidi_context *ctx = get_vidi_context(subdrv_dev);
- DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
+ DRM_DEBUG_KMS("%d\n", mode);
mutex_lock(&ctx->lock);
@@ -196,8 +186,6 @@ static void vidi_apply(struct device *subdrv_dev)
struct vidi_win_data *win_data;
int i;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
if (win_data->enabled && (ovl_ops && ovl_ops->commit))
@@ -212,8 +200,6 @@ static void vidi_commit(struct device *dev)
{
struct vidi_context *ctx = get_vidi_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ctx->suspended)
return;
}
@@ -222,8 +208,6 @@ static int vidi_enable_vblank(struct device *dev)
{
struct vidi_context *ctx = get_vidi_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ctx->suspended)
return -EPERM;
@@ -246,8 +230,6 @@ static void vidi_disable_vblank(struct device *dev)
{
struct vidi_context *ctx = get_vidi_context(dev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ctx->suspended)
return;
@@ -271,8 +253,6 @@ static void vidi_win_mode_set(struct device *dev,
int win;
unsigned long offset;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (!overlay) {
dev_err(dev, "overlay is NULL\n");
return;
@@ -282,7 +262,7 @@ static void vidi_win_mode_set(struct device *dev,
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
- if (win < 0 || win > WINDOWS_NR)
+ if (win < 0 || win >= WINDOWS_NR)
return;
offset = overlay->fb_x * (overlay->bpp >> 3);
@@ -324,15 +304,13 @@ static void vidi_win_commit(struct device *dev, int zpos)
struct vidi_win_data *win_data;
int win = zpos;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (ctx->suspended)
return;
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
- if (win < 0 || win > WINDOWS_NR)
+ if (win < 0 || win >= WINDOWS_NR)
return;
win_data = &ctx->win_data[win];
@@ -351,12 +329,10 @@ static void vidi_win_disable(struct device *dev, int zpos)
struct vidi_win_data *win_data;
int win = zpos;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
- if (win < 0 || win > WINDOWS_NR)
+ if (win < 0 || win >= WINDOWS_NR)
return;
win_data = &ctx->win_data[win];
@@ -407,8 +383,6 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/*
* enable drm irq mode.
* - with irq_enabled = 1, we can use the vblank feature.
@@ -431,8 +405,6 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
/* TODO. */
}
@@ -441,8 +413,6 @@ static int vidi_power_on(struct vidi_context *ctx, bool enable)
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct device *dev = subdrv->dev;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (enable != false && enable != true)
return -EINVAL;
@@ -483,8 +453,6 @@ static int vidi_store_connection(struct device *dev,
struct vidi_context *ctx = get_vidi_context(dev);
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
ret = kstrtoint(buf, 0, &ctx->connected);
if (ret)
return ret;
@@ -522,8 +490,6 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
struct drm_exynos_vidi_connection *vidi = data;
int edid_len;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
if (!vidi) {
DRM_DEBUG_KMS("user data for vidi is null.\n");
return -EINVAL;
@@ -592,8 +558,6 @@ static int vidi_probe(struct platform_device *pdev)
struct exynos_drm_subdrv *subdrv;
int ret;
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
@@ -625,8 +589,6 @@ static int vidi_remove(struct platform_device *pdev)
{
struct vidi_context *ctx = platform_get_drvdata(pdev);
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
exynos_drm_subdrv_unregister(&ctx->subdrv);
if (ctx->raw_edid != (struct edid *)fake_edid_info) {
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index fd1426dca882..62ef5971ac3c 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -83,6 +83,7 @@ struct hdmi_resources {
struct clk *sclk_pixel;
struct clk *sclk_hdmiphy;
struct clk *hdmiphy;
+ struct clk *mout_hdmi;
struct regulator_bulk_data *regul_bulk;
int regul_count;
};
@@ -689,8 +690,6 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata,
u32 mod;
u32 vic;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
if (hdata->dvi_mode) {
hdmi_reg_writeb(hdata, HDMI_VSI_CON,
@@ -755,8 +754,6 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
struct edid *raw_edid;
struct hdmi_context *hdata = ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (!hdata->ddc_port)
return ERR_PTR(-ENODEV);
@@ -777,8 +774,6 @@ static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
const struct hdmiphy_config *confs;
int count, i;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (hdata->type == HDMI_TYPE13) {
confs = hdmiphy_v13_configs;
count = ARRAY_SIZE(hdmiphy_v13_configs);
@@ -796,18 +791,17 @@ static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
return -EINVAL;
}
-static int hdmi_check_timing(void *ctx, struct fb_videomode *timing)
+static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
{
struct hdmi_context *hdata = ctx;
int ret;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+ DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
+ mode->hdisplay, mode->vdisplay, mode->vrefresh,
+ (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
+ false, mode->clock * 1000);
- DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", timing->xres,
- timing->yres, timing->refresh,
- timing->vmode);
-
- ret = hdmi_find_phy_conf(hdata, timing->pixclock);
+ ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
if (ret < 0)
return ret;
return 0;
@@ -1042,7 +1036,7 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
}
}
-static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
+static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
{
const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
const struct hdmi_v13_core_regs *core =
@@ -1118,9 +1112,9 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
hdmi_regs_dump(hdata, "timing apply");
}
- clk_disable(hdata->res.sclk_hdmi);
- clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
- clk_enable(hdata->res.sclk_hdmi);
+ clk_disable_unprepare(hdata->res.sclk_hdmi);
+ clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
+ clk_prepare_enable(hdata->res.sclk_hdmi);
/* enable HDMI and timing generator */
hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
@@ -1131,7 +1125,7 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
}
-static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
+static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
{
const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
const struct hdmi_v14_core_regs *core =
@@ -1285,9 +1279,9 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
hdmi_regs_dump(hdata, "timing apply");
}
- clk_disable(hdata->res.sclk_hdmi);
- clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
- clk_enable(hdata->res.sclk_hdmi);
+ clk_disable_unprepare(hdata->res.sclk_hdmi);
+ clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
+ clk_prepare_enable(hdata->res.sclk_hdmi);
/* enable HDMI and timing generator */
hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
@@ -1298,12 +1292,12 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
}
-static void hdmi_timing_apply(struct hdmi_context *hdata)
+static void hdmi_mode_apply(struct hdmi_context *hdata)
{
if (hdata->type == HDMI_TYPE13)
- hdmi_v13_timing_apply(hdata);
+ hdmi_v13_mode_apply(hdata);
else
- hdmi_v14_timing_apply(hdata);
+ hdmi_v14_mode_apply(hdata);
}
static void hdmiphy_conf_reset(struct hdmi_context *hdata)
@@ -1311,9 +1305,9 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
u8 buffer[2];
u32 reg;
- clk_disable(hdata->res.sclk_hdmi);
- clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
- clk_enable(hdata->res.sclk_hdmi);
+ clk_disable_unprepare(hdata->res.sclk_hdmi);
+ clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
+ clk_prepare_enable(hdata->res.sclk_hdmi);
/* operation mode */
buffer[0] = 0x1f;
@@ -1336,8 +1330,6 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
static void hdmiphy_poweron(struct hdmi_context *hdata)
{
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (hdata->type == HDMI_TYPE14)
hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0,
HDMI_PHY_POWER_OFF_EN);
@@ -1345,8 +1337,6 @@ static void hdmiphy_poweron(struct hdmi_context *hdata)
static void hdmiphy_poweroff(struct hdmi_context *hdata)
{
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (hdata->type == HDMI_TYPE14)
hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0,
HDMI_PHY_POWER_OFF_EN);
@@ -1410,8 +1400,6 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
static void hdmi_conf_apply(struct hdmi_context *hdata)
{
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
hdmiphy_conf_reset(hdata);
hdmiphy_conf_apply(hdata);
@@ -1423,7 +1411,7 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
hdmi_audio_init(hdata);
/* setting core registers */
- hdmi_timing_apply(hdata);
+ hdmi_mode_apply(hdata);
hdmi_audio_control(hdata, true);
hdmi_regs_dump(hdata, "start");
@@ -1569,8 +1557,7 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
(m->vsync_start - m->vdisplay) / 2);
hdmi_set_reg(core->v2_blank, 2, m->vtotal / 2);
hdmi_set_reg(core->v1_blank, 2, (m->vtotal - m->vdisplay) / 2);
- hdmi_set_reg(core->v_blank_f0, 2, (m->vtotal +
- ((m->vsync_end - m->vsync_start) * 4) + 5) / 2);
+ hdmi_set_reg(core->v_blank_f0, 2, m->vtotal - m->vdisplay / 2);
hdmi_set_reg(core->v_blank_f1, 2, m->vtotal);
hdmi_set_reg(core->v_sync_line_aft_2, 2, (m->vtotal / 2) + 7);
hdmi_set_reg(core->v_sync_line_aft_1, 2, (m->vtotal / 2) + 2);
@@ -1580,7 +1567,10 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
(m->htotal / 2) + (m->hsync_start - m->hdisplay));
hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
- hdmi_set_reg(tg->vact_st2, 2, 0x249);/* Reset value + 1*/
+ hdmi_set_reg(tg->vact_st2, 2, m->vtotal - m->vdisplay / 2);
+ hdmi_set_reg(tg->vsync2, 2, (m->vtotal / 2) + 1);
+ hdmi_set_reg(tg->vsync_bot_hdmi, 2, (m->vtotal / 2) + 1);
+ hdmi_set_reg(tg->field_bot_hdmi, 2, (m->vtotal / 2) + 1);
hdmi_set_reg(tg->vact_st3, 2, 0x0);
hdmi_set_reg(tg->vact_st4, 2, 0x0);
} else {
@@ -1602,6 +1592,9 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
hdmi_set_reg(tg->vact_st3, 2, 0x47b); /* Reset value */
hdmi_set_reg(tg->vact_st4, 2, 0x6ae); /* Reset value */
+ hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
+ hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
+ hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
}
/* Following values & calculations are same irrespective of mode type */
@@ -1633,22 +1626,19 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
hdmi_set_reg(tg->vsync, 2, 0x1);
- hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
- hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
- hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
hdmi_set_reg(tg->tg_3d, 1, 0x0);
}
-static void hdmi_mode_set(void *ctx, void *mode)
+static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
{
struct hdmi_context *hdata = ctx;
struct drm_display_mode *m = mode;
- DRM_DEBUG_KMS("[%s]: xres=%d, yres=%d, refresh=%d, intl=%s\n",
- __func__, m->hdisplay, m->vdisplay,
+ DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
+ m->hdisplay, m->vdisplay,
m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
"INTERLACED" : "PROGERESSIVE");
@@ -1661,8 +1651,6 @@ static void hdmi_mode_set(void *ctx, void *mode)
static void hdmi_get_max_resol(void *ctx, unsigned int *width,
unsigned int *height)
{
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
*width = MAX_WIDTH;
*height = MAX_HEIGHT;
}
@@ -1671,8 +1659,6 @@ static void hdmi_commit(void *ctx)
{
struct hdmi_context *hdata = ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mutex_lock(&hdata->hdmi_mutex);
if (!hdata->powered) {
mutex_unlock(&hdata->hdmi_mutex);
@@ -1687,8 +1673,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
{
struct hdmi_resources *res = &hdata->res;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mutex_lock(&hdata->hdmi_mutex);
if (hdata->powered) {
mutex_unlock(&hdata->hdmi_mutex);
@@ -1699,10 +1683,12 @@ static void hdmi_poweron(struct hdmi_context *hdata)
mutex_unlock(&hdata->hdmi_mutex);
- regulator_bulk_enable(res->regul_count, res->regul_bulk);
- clk_enable(res->hdmiphy);
- clk_enable(res->hdmi);
- clk_enable(res->sclk_hdmi);
+ if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
+ DRM_DEBUG_KMS("failed to enable regulator bulk\n");
+
+ clk_prepare_enable(res->hdmiphy);
+ clk_prepare_enable(res->hdmi);
+ clk_prepare_enable(res->sclk_hdmi);
hdmiphy_poweron(hdata);
}
@@ -1711,8 +1697,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
{
struct hdmi_resources *res = &hdata->res;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mutex_lock(&hdata->hdmi_mutex);
if (!hdata->powered)
goto out;
@@ -1725,9 +1709,9 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
hdmiphy_conf_reset(hdata);
hdmiphy_poweroff(hdata);
- clk_disable(res->sclk_hdmi);
- clk_disable(res->hdmi);
- clk_disable(res->hdmiphy);
+ clk_disable_unprepare(res->sclk_hdmi);
+ clk_disable_unprepare(res->hdmi);
+ clk_disable_unprepare(res->hdmiphy);
regulator_bulk_disable(res->regul_count, res->regul_bulk);
mutex_lock(&hdata->hdmi_mutex);
@@ -1742,7 +1726,7 @@ static void hdmi_dpms(void *ctx, int mode)
{
struct hdmi_context *hdata = ctx;
- DRM_DEBUG_KMS("[%d] %s mode %d\n", __LINE__, __func__, mode);
+ DRM_DEBUG_KMS("mode %d\n", mode);
switch (mode) {
case DRM_MODE_DPMS_ON:
@@ -1765,7 +1749,7 @@ static struct exynos_hdmi_ops hdmi_ops = {
/* display */
.is_connected = hdmi_is_connected,
.get_edid = hdmi_get_edid,
- .check_timing = hdmi_check_timing,
+ .check_mode = hdmi_check_mode,
/* manager */
.mode_set = hdmi_mode_set,
@@ -1831,8 +1815,13 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
DRM_ERROR("failed to get clock 'hdmiphy'\n");
goto fail;
}
+ res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
+ if (IS_ERR(res->mout_hdmi)) {
+ DRM_ERROR("failed to get clock 'mout_hdmi'\n");
+ goto fail;
+ }
- clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
+ clk_set_parent(res->mout_hdmi, res->sclk_pixel);
res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
sizeof(res->regul_bulk[0]), GFP_KERNEL);
@@ -1877,7 +1866,6 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
{
struct device_node *np = dev->of_node;
struct s5p_hdmi_platform_data *pd;
- enum of_gpio_flags flags;
u32 value;
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
@@ -1891,7 +1879,7 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
goto err_data;
}
- pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
+ pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
return pd;
@@ -1930,6 +1918,9 @@ static struct of_device_id hdmi_match_types[] = {
.compatible = "samsung,exynos5-hdmi",
.data = (void *)HDMI_TYPE14,
}, {
+ .compatible = "samsung,exynos4212-hdmi",
+ .data = (void *)HDMI_TYPE14,
+ }, {
/* end node */
}
};
@@ -1944,8 +1935,6 @@ static int hdmi_probe(struct platform_device *pdev)
struct resource *res;
int ret;
- DRM_DEBUG_KMS("[%d]\n", __LINE__);
-
if (dev->of_node) {
pdata = drm_hdmi_dt_parse_pdata(dev);
if (IS_ERR(pdata)) {
@@ -2071,8 +2060,6 @@ static int hdmi_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
pm_runtime_disable(dev);
/* hdmiphy i2c driver */
@@ -2089,8 +2076,6 @@ static int hdmi_suspend(struct device *dev)
struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
struct hdmi_context *hdata = ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
disable_irq(hdata->irq);
hdata->hpd = false;
@@ -2098,7 +2083,7 @@ static int hdmi_suspend(struct device *dev)
drm_helper_hpd_irq_event(ctx->drm_dev);
if (pm_runtime_suspended(dev)) {
- DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
+ DRM_DEBUG_KMS("Already suspended\n");
return 0;
}
@@ -2112,14 +2097,12 @@ static int hdmi_resume(struct device *dev)
struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
struct hdmi_context *hdata = ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
hdata->hpd = gpio_get_value(hdata->hpd_gpio);
enable_irq(hdata->irq);
if (!pm_runtime_suspended(dev)) {
- DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
+ DRM_DEBUG_KMS("Already resumed\n");
return 0;
}
@@ -2134,7 +2117,6 @@ static int hdmi_runtime_suspend(struct device *dev)
{
struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
struct hdmi_context *hdata = ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
hdmi_poweroff(hdata);
@@ -2145,7 +2127,6 @@ static int hdmi_runtime_resume(struct device *dev)
{
struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
struct hdmi_context *hdata = ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
hdmi_poweron(hdata);
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
index ea49d132ecf6..ef04255076c7 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
@@ -51,6 +51,10 @@ static struct of_device_id hdmiphy_match_types[] = {
{
.compatible = "samsung,exynos5-hdmiphy",
}, {
+ .compatible = "samsung,exynos4210-hdmiphy",
+ }, {
+ .compatible = "samsung,exynos4212-hdmiphy",
+ }, {
/* end node */
}
};
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 7c197d3820c5..b1280b43931c 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -78,6 +78,7 @@ struct mixer_resources {
enum mixer_version_id {
MXR_VER_0_0_0_16,
MXR_VER_16_0_33_0,
+ MXR_VER_128_0_0_184,
};
struct mixer_context {
@@ -283,17 +284,19 @@ static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
MXR_CFG_SCAN_PROGRASSIVE);
- /* choosing between porper HD and SD mode */
- if (height <= 480)
- val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
- else if (height <= 576)
- val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
- else if (height <= 720)
- val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
- else if (height <= 1080)
- val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
- else
- val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
+ if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
+ /* choosing between proper HD and SD mode */
+ if (height <= 480)
+ val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
+ else if (height <= 576)
+ val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
+ else if (height <= 720)
+ val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
+ else if (height <= 1080)
+ val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
+ else
+ val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
+ }
mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
}
@@ -557,6 +560,14 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
/* setup geometry */
mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
+ /* setup display size */
+ if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
+ win == MIXER_DEFAULT_WIN) {
+ val = MXR_MXR_RES_HEIGHT(win_data->fb_height);
+ val |= MXR_MXR_RES_WIDTH(win_data->fb_width);
+ mixer_reg_write(res, MXR_RESOLUTION, val);
+ }
+
val = MXR_GRP_WH_WIDTH(win_data->crtc_width);
val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height);
val |= MXR_GRP_WH_H_SCALE(x_ratio);
@@ -581,7 +592,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
mixer_cfg_layer(ctx, win, true);
/* layer update mandatory for mixer 16.0.33.0 */
- if (ctx->mxr_ver == MXR_VER_16_0_33_0)
+ if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
+ ctx->mxr_ver == MXR_VER_128_0_0_184)
mixer_layer_update(ctx);
mixer_run(ctx);
@@ -696,8 +708,6 @@ static int mixer_enable_vblank(void *ctx, int pipe)
struct mixer_context *mixer_ctx = ctx;
struct mixer_resources *res = &mixer_ctx->mixer_res;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mixer_ctx->pipe = pipe;
/* enable vsync interrupt */
@@ -712,8 +722,6 @@ static void mixer_disable_vblank(void *ctx)
struct mixer_context *mixer_ctx = ctx;
struct mixer_resources *res = &mixer_ctx->mixer_res;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
/* disable vsync interrupt */
mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
}
@@ -725,8 +733,6 @@ static void mixer_win_mode_set(void *ctx,
struct hdmi_win_data *win_data;
int win;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (!overlay) {
DRM_ERROR("overlay is NULL\n");
return;
@@ -742,7 +748,7 @@ static void mixer_win_mode_set(void *ctx,
if (win == DEFAULT_ZPOS)
win = MIXER_DEFAULT_WIN;
- if (win < 0 || win > MIXER_WIN_NR) {
+ if (win < 0 || win >= MIXER_WIN_NR) {
DRM_ERROR("mixer window[%d] is wrong\n", win);
return;
}
@@ -776,7 +782,7 @@ static void mixer_win_commit(void *ctx, int win)
{
struct mixer_context *mixer_ctx = ctx;
- DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
+ DRM_DEBUG_KMS("win: %d\n", win);
mutex_lock(&mixer_ctx->mixer_mutex);
if (!mixer_ctx->powered) {
@@ -799,7 +805,7 @@ static void mixer_win_disable(void *ctx, int win)
struct mixer_resources *res = &mixer_ctx->mixer_res;
unsigned long flags;
- DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
+ DRM_DEBUG_KMS("win: %d\n", win);
mutex_lock(&mixer_ctx->mixer_mutex);
if (!mixer_ctx->powered) {
@@ -820,17 +826,21 @@ static void mixer_win_disable(void *ctx, int win)
mixer_ctx->win_data[win].enabled = false;
}
-static int mixer_check_timing(void *ctx, struct fb_videomode *timing)
+static int mixer_check_mode(void *ctx, struct drm_display_mode *mode)
{
+ struct mixer_context *mixer_ctx = ctx;
u32 w, h;
- w = timing->xres;
- h = timing->yres;
+ w = mode->hdisplay;
+ h = mode->vdisplay;
- DRM_DEBUG_KMS("%s : xres=%d, yres=%d, refresh=%d, intl=%d\n",
- __func__, timing->xres, timing->yres,
- timing->refresh, (timing->vmode &
- FB_VMODE_INTERLACED) ? true : false);
+ DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
+ mode->hdisplay, mode->vdisplay, mode->vrefresh,
+ (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
+
+ if (mixer_ctx->mxr_ver == MXR_VER_0_0_0_16 ||
+ mixer_ctx->mxr_ver == MXR_VER_128_0_0_184)
+ return 0;
if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
(w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
@@ -891,8 +901,6 @@ static void mixer_poweron(struct mixer_context *ctx)
{
struct mixer_resources *res = &ctx->mixer_res;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mutex_lock(&ctx->mixer_mutex);
if (ctx->powered) {
mutex_unlock(&ctx->mixer_mutex);
@@ -901,10 +909,10 @@ static void mixer_poweron(struct mixer_context *ctx)
ctx->powered = true;
mutex_unlock(&ctx->mixer_mutex);
- clk_enable(res->mixer);
+ clk_prepare_enable(res->mixer);
if (ctx->vp_enabled) {
- clk_enable(res->vp);
- clk_enable(res->sclk_mixer);
+ clk_prepare_enable(res->vp);
+ clk_prepare_enable(res->sclk_mixer);
}
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
@@ -917,8 +925,6 @@ static void mixer_poweroff(struct mixer_context *ctx)
{
struct mixer_resources *res = &ctx->mixer_res;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mutex_lock(&ctx->mixer_mutex);
if (!ctx->powered)
goto out;
@@ -928,10 +934,10 @@ static void mixer_poweroff(struct mixer_context *ctx)
ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
- clk_disable(res->mixer);
+ clk_disable_unprepare(res->mixer);
if (ctx->vp_enabled) {
- clk_disable(res->vp);
- clk_disable(res->sclk_mixer);
+ clk_disable_unprepare(res->vp);
+ clk_disable_unprepare(res->sclk_mixer);
}
mutex_lock(&ctx->mixer_mutex);
@@ -945,8 +951,6 @@ static void mixer_dpms(void *ctx, int mode)
{
struct mixer_context *mixer_ctx = ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
switch (mode) {
case DRM_MODE_DPMS_ON:
if (pm_runtime_suspended(mixer_ctx->dev))
@@ -978,7 +982,7 @@ static struct exynos_mixer_ops mixer_ops = {
.win_disable = mixer_win_disable,
/* display */
- .check_timing = mixer_check_timing,
+ .check_mode = mixer_check_mode,
};
static irqreturn_t mixer_irq_handler(int irq, void *arg)
@@ -1128,12 +1132,17 @@ static int vp_resources_init(struct exynos_drm_hdmi_context *ctx,
return 0;
}
-static struct mixer_drv_data exynos5_mxr_drv_data = {
+static struct mixer_drv_data exynos5420_mxr_drv_data = {
+ .version = MXR_VER_128_0_0_184,
+ .is_vp_enabled = 0,
+};
+
+static struct mixer_drv_data exynos5250_mxr_drv_data = {
.version = MXR_VER_16_0_33_0,
.is_vp_enabled = 0,
};
-static struct mixer_drv_data exynos4_mxr_drv_data = {
+static struct mixer_drv_data exynos4210_mxr_drv_data = {
.version = MXR_VER_0_0_0_16,
.is_vp_enabled = 1,
};
@@ -1141,10 +1150,10 @@ static struct mixer_drv_data exynos4_mxr_drv_data = {
static struct platform_device_id mixer_driver_types[] = {
{
.name = "s5p-mixer",
- .driver_data = (unsigned long)&exynos4_mxr_drv_data,
+ .driver_data = (unsigned long)&exynos4210_mxr_drv_data,
}, {
.name = "exynos5-mixer",
- .driver_data = (unsigned long)&exynos5_mxr_drv_data,
+ .driver_data = (unsigned long)&exynos5250_mxr_drv_data,
}, {
/* end node */
}
@@ -1153,7 +1162,13 @@ static struct platform_device_id mixer_driver_types[] = {
static struct of_device_id mixer_match_types[] = {
{
.compatible = "samsung,exynos5-mixer",
- .data = &exynos5_mxr_drv_data,
+ .data = &exynos5250_mxr_drv_data,
+ }, {
+ .compatible = "samsung,exynos5250-mixer",
+ .data = &exynos5250_mxr_drv_data,
+ }, {
+ .compatible = "samsung,exynos5420-mixer",
+ .data = &exynos5420_mxr_drv_data,
}, {
/* end node */
}
@@ -1186,8 +1201,7 @@ static int mixer_probe(struct platform_device *pdev)
if (dev->of_node) {
const struct of_device_id *match;
- match = of_match_node(of_match_ptr(mixer_match_types),
- dev->of_node);
+ match = of_match_node(mixer_match_types, dev->of_node);
drv = (struct mixer_drv_data *)match->data;
} else {
drv = (struct mixer_drv_data *)
@@ -1251,10 +1265,8 @@ static int mixer_suspend(struct device *dev)
struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
struct mixer_context *ctx = drm_hdmi_ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (pm_runtime_suspended(dev)) {
- DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
+ DRM_DEBUG_KMS("Already suspended\n");
return 0;
}
@@ -1268,10 +1280,8 @@ static int mixer_resume(struct device *dev)
struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
struct mixer_context *ctx = drm_hdmi_ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
if (!pm_runtime_suspended(dev)) {
- DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
+ DRM_DEBUG_KMS("Already resumed\n");
return 0;
}
@@ -1287,8 +1297,6 @@ static int mixer_runtime_suspend(struct device *dev)
struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
struct mixer_context *ctx = drm_hdmi_ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mixer_poweroff(ctx);
return 0;
@@ -1299,8 +1307,6 @@ static int mixer_runtime_resume(struct device *dev)
struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
struct mixer_context *ctx = drm_hdmi_ctx->ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
mixer_poweron(ctx);
return 0;
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h
index 5d8dbc0301e6..4537026bc385 100644
--- a/drivers/gpu/drm/exynos/regs-mixer.h
+++ b/drivers/gpu/drm/exynos/regs-mixer.h
@@ -44,6 +44,9 @@
#define MXR_CM_COEFF_Y 0x0080
#define MXR_CM_COEFF_CB 0x0084
#define MXR_CM_COEFF_CR 0x0088
+#define MXR_MO 0x0304
+#define MXR_RESOLUTION 0x0310
+
#define MXR_GRAPHIC0_BASE_S 0x2024
#define MXR_GRAPHIC1_BASE_S 0x2044
@@ -119,6 +122,10 @@
#define MXR_GRP_WH_WIDTH(x) MXR_MASK_VAL(x, 26, 16)
#define MXR_GRP_WH_HEIGHT(x) MXR_MASK_VAL(x, 10, 0)
+/* bits for MXR_RESOLUTION */
+#define MXR_MXR_RES_HEIGHT(x) MXR_MASK_VAL(x, 26, 16)
+#define MXR_MXR_RES_WIDTH(x) MXR_MASK_VAL(x, 10, 0)
+
/* bits for MXR_GRAPHICn_SXY */
#define MXR_GRP_SXY_SX(x) MXR_MASK_VAL(x, 26, 16)
#define MXR_GRP_SXY_SY(x) MXR_MASK_VAL(x, 10, 0)
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 998e8b4444f3..b59cfd79bd79 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -12,7 +12,6 @@ nouveau-y += core/core/engctx.o
nouveau-y += core/core/engine.o
nouveau-y += core/core/enum.o
nouveau-y += core/core/event.o
-nouveau-y += core/core/falcon.o
nouveau-y += core/core/gpuobj.o
nouveau-y += core/core/handle.o
nouveau-y += core/core/mm.o
@@ -60,6 +59,8 @@ nouveau-y += core/subdev/devinit/nv10.o
nouveau-y += core/subdev/devinit/nv1a.o
nouveau-y += core/subdev/devinit/nv20.o
nouveau-y += core/subdev/devinit/nv50.o
+nouveau-y += core/subdev/devinit/nva3.o
+nouveau-y += core/subdev/devinit/nvc0.o
nouveau-y += core/subdev/fb/base.o
nouveau-y += core/subdev/fb/nv04.o
nouveau-y += core/subdev/fb/nv10.o
@@ -78,6 +79,17 @@ nouveau-y += core/subdev/fb/nv49.o
nouveau-y += core/subdev/fb/nv4e.o
nouveau-y += core/subdev/fb/nv50.o
nouveau-y += core/subdev/fb/nvc0.o
+nouveau-y += core/subdev/fb/ramnv04.o
+nouveau-y += core/subdev/fb/ramnv10.o
+nouveau-y += core/subdev/fb/ramnv1a.o
+nouveau-y += core/subdev/fb/ramnv20.o
+nouveau-y += core/subdev/fb/ramnv40.o
+nouveau-y += core/subdev/fb/ramnv41.o
+nouveau-y += core/subdev/fb/ramnv44.o
+nouveau-y += core/subdev/fb/ramnv49.o
+nouveau-y += core/subdev/fb/ramnv4e.o
+nouveau-y += core/subdev/fb/ramnv50.o
+nouveau-y += core/subdev/fb/ramnvc0.o
nouveau-y += core/subdev/gpio/base.o
nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv50.o
@@ -129,12 +141,15 @@ nouveau-y += core/subdev/vm/nv44.o
nouveau-y += core/subdev/vm/nv50.o
nouveau-y += core/subdev/vm/nvc0.o
+nouveau-y += core/engine/falcon.o
+nouveau-y += core/engine/xtensa.o
nouveau-y += core/engine/dmaobj/base.o
nouveau-y += core/engine/dmaobj/nv04.o
nouveau-y += core/engine/dmaobj/nv50.o
nouveau-y += core/engine/dmaobj/nvc0.o
nouveau-y += core/engine/dmaobj/nvd0.o
nouveau-y += core/engine/bsp/nv84.o
+nouveau-y += core/engine/bsp/nv98.o
nouveau-y += core/engine/bsp/nvc0.o
nouveau-y += core/engine/bsp/nve0.o
nouveau-y += core/engine/copy/nva3.o
@@ -209,6 +224,7 @@ nouveau-y += core/engine/software/nv10.o
nouveau-y += core/engine/software/nv50.o
nouveau-y += core/engine/software/nvc0.o
nouveau-y += core/engine/vp/nv84.o
+nouveau-y += core/engine/vp/nv98.o
nouveau-y += core/engine/vp/nvc0.o
nouveau-y += core/engine/vp/nve0.o
diff --git a/drivers/gpu/drm/nouveau/core/core/mm.c b/drivers/gpu/drm/nouveau/core/core/mm.c
index 0261a11b2ae0..d8291724dbd4 100644
--- a/drivers/gpu/drm/nouveau/core/core/mm.c
+++ b/drivers/gpu/drm/nouveau/core/core/mm.c
@@ -208,7 +208,6 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
struct nouveau_mm_node *node;
if (block) {
- mutex_init(&mm->mutex);
INIT_LIST_HEAD(&mm->nodes);
INIT_LIST_HEAD(&mm->free);
mm->block_size = block;
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c
index 1d9f614cb97d..1e8e75c0684a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c
@@ -19,24 +19,19 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs, Ilia Mirkin
*/
-#include <core/engctx.h>
-#include <core/class.h>
-
+#include <engine/xtensa.h>
#include <engine/bsp.h>
-struct nv84_bsp_priv {
- struct nouveau_engine base;
-};
-
/*******************************************************************************
* BSP object classes
******************************************************************************/
static struct nouveau_oclass
nv84_bsp_sclass[] = {
+ { 0x74b0, &nouveau_object_ofuncs },
{},
};
@@ -48,7 +43,7 @@ static struct nouveau_oclass
nv84_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_engctx_ctor,
+ .ctor = _nouveau_xtensa_engctx_ctor,
.dtor = _nouveau_engctx_dtor,
.init = _nouveau_engctx_init,
.fini = _nouveau_engctx_fini,
@@ -66,10 +61,10 @@ nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv84_bsp_priv *priv;
+ struct nouveau_xtensa *priv;
int ret;
- ret = nouveau_engine_create(parent, engine, oclass, true,
+ ret = nouveau_xtensa_create(parent, engine, oclass, 0x103000, true,
"PBSP", "bsp", &priv);
*pobject = nv_object(priv);
if (ret)
@@ -78,6 +73,8 @@ nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->unit = 0x04008000;
nv_engine(priv)->cclass = &nv84_bsp_cclass;
nv_engine(priv)->sclass = nv84_bsp_sclass;
+ priv->fifo_val = 0x1111;
+ priv->unkd28 = 0x90044;
return 0;
}
@@ -86,8 +83,10 @@ nv84_bsp_oclass = {
.handle = NV_ENGINE(BSP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_bsp_ctor,
- .dtor = _nouveau_engine_dtor,
- .init = _nouveau_engine_init,
- .fini = _nouveau_engine_fini,
+ .dtor = _nouveau_xtensa_dtor,
+ .init = _nouveau_xtensa_init,
+ .fini = _nouveau_xtensa_fini,
+ .rd32 = _nouveau_xtensa_rd32,
+ .wr32 = _nouveau_xtensa_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c
new file mode 100644
index 000000000000..8bf92b0e6d82
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/engctx.h>
+#include <core/class.h>
+
+#include <engine/bsp.h>
+
+struct nv98_bsp_priv {
+ struct nouveau_engine base;
+};
+
+/*******************************************************************************
+ * BSP object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_bsp_sclass[] = {
+ {},
+};
+
+/*******************************************************************************
+ * BSP context
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_bsp_cclass = {
+ .handle = NV_ENGCTX(BSP, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = _nouveau_engctx_ctor,
+ .dtor = _nouveau_engctx_dtor,
+ .init = _nouveau_engctx_init,
+ .fini = _nouveau_engctx_fini,
+ .rd32 = _nouveau_engctx_rd32,
+ .wr32 = _nouveau_engctx_wr32,
+ },
+};
+
+/*******************************************************************************
+ * BSP engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv98_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_bsp_priv *priv;
+ int ret;
+
+ ret = nouveau_engine_create(parent, engine, oclass, true,
+ "PBSP", "bsp", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x04008000;
+ nv_engine(priv)->cclass = &nv98_bsp_cclass;
+ nv_engine(priv)->sclass = nv98_bsp_sclass;
+ return 0;
+}
+
+struct nouveau_oclass
+nv98_bsp_oclass = {
+ .handle = NV_ENGINE(BSP, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_bsp_ctor,
+ .dtor = _nouveau_engine_dtor,
+ .init = _nouveau_engine_init,
+ .fini = _nouveau_engine_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c
index 0a5aa6bb0870..262c9f5f5f60 100644
--- a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c
@@ -22,8 +22,7 @@
* Authors: Maarten Lankhorst
*/
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
#include <engine/bsp.h>
struct nvc0_bsp_priv {
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c
index d4f23bbd75b4..c46882c83982 100644
--- a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c
@@ -22,8 +22,7 @@
* Authors: Ben Skeggs
*/
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
#include <engine/bsp.h>
struct nve0_bsp_priv {
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
index c92520f3ed46..241b27201206 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
@@ -1,4 +1,4 @@
-static u32 nva3_pcopy_data[] = {
+uint32_t nva3_pcopy_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_dma */
@@ -183,7 +183,7 @@ static u32 nva3_pcopy_data[] = {
0x00000800,
};
-static u32 nva3_pcopy_code[] = {
+uint32_t nva3_pcopy_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
index 0d98c6c0958d..98cc4216a372 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
@@ -1,4 +1,4 @@
-static u32 nvc0_pcopy_data[] = {
+uint32_t nvc0_pcopy_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_query_address_high */
@@ -171,7 +171,7 @@ static u32 nvc0_pcopy_data[] = {
0x00000800,
};
-static u32 nvc0_pcopy_code[] = {
+uint32_t nvc0_pcopy_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
index d6dc2a65ccd1..f31527733e00 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
@@ -22,16 +22,17 @@
* Authors: Ben Skeggs
*/
-#include <core/client.h>
-#include <core/falcon.h>
-#include <core/class.h>
-#include <core/enum.h>
+#include <engine/falcon.h>
+#include <engine/fifo.h>
+#include <engine/copy.h>
#include <subdev/fb.h>
#include <subdev/vm.h>
-#include <engine/fifo.h>
-#include <engine/copy.h>
+#include <core/client.h>
+#include <core/class.h>
+#include <core/enum.h>
+
#include "fuc/nva3.fuc.h"
@@ -117,13 +118,6 @@ nva3_copy_intr(struct nouveau_subdev *subdev)
}
static int
-nva3_copy_tlb_flush(struct nouveau_engine *engine)
-{
- nv50_vm_flush_engine(&engine->base, 0x0d);
- return 0;
-}
-
-static int
nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -142,7 +136,6 @@ nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nva3_copy_intr;
nv_engine(priv)->cclass = &nva3_copy_cclass;
nv_engine(priv)->sclass = nva3_copy_sclass;
- nv_engine(priv)->tlb_flush = nva3_copy_tlb_flush;
nv_falcon(priv)->code.data = nva3_pcopy_code;
nv_falcon(priv)->code.size = sizeof(nva3_pcopy_code);
nv_falcon(priv)->data.data = nva3_pcopy_data;
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
index b3ed2737e21f..993df09ad643 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
@@ -22,13 +22,15 @@
* Authors: Ben Skeggs
*/
-#include <core/falcon.h>
-#include <core/class.h>
-#include <core/enum.h>
-
+#include <engine/falcon.h>
#include <engine/fifo.h>
#include <engine/copy.h>
+#include <core/class.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/enum.h>
+
#include "fuc/nvc0.fuc.h"
struct nvc0_copy_priv {
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
index dbbe9e8998fe..30f1ef1edcc5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
@@ -67,6 +67,19 @@ nve0_copy_cclass = {
* PCOPY engine/subdev functions
******************************************************************************/
+static void
+nve0_copy_intr(struct nouveau_subdev *subdev)
+{
+ const int ce = nv_subidx(nv_object(subdev)) - NVDEV_ENGINE_COPY0;
+ struct nve0_copy_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, 0x104908 + (ce * 0x1000));
+
+ if (stat) {
+ nv_warn(priv, "unhandled intr 0x%08x\n", stat);
+ nv_wr32(priv, 0x104908 + (ce * 0x1000), stat);
+ }
+}
+
static int
nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
@@ -85,6 +98,7 @@ nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
nv_subdev(priv)->unit = 0x00000040;
+ nv_subdev(priv)->intr = nve0_copy_intr;
nv_engine(priv)->cclass = &nve0_copy_cclass;
nv_engine(priv)->sclass = nve0_copy_sclass;
return 0;
@@ -108,6 +122,28 @@ nve0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
nv_subdev(priv)->unit = 0x00000080;
+ nv_subdev(priv)->intr = nve0_copy_intr;
+ nv_engine(priv)->cclass = &nve0_copy_cclass;
+ nv_engine(priv)->sclass = nve0_copy_sclass;
+ return 0;
+}
+
+static int
+nve0_copy2_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nve0_copy_priv *priv;
+ int ret;
+
+ ret = nouveau_engine_create(parent, engine, oclass, true,
+ "PCE2", "copy2", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00200000;
+ nv_subdev(priv)->intr = nve0_copy_intr;
nv_engine(priv)->cclass = &nve0_copy_cclass;
nv_engine(priv)->sclass = nve0_copy_sclass;
return 0;
@@ -134,3 +170,14 @@ nve0_copy1_oclass = {
.fini = _nouveau_engine_fini,
},
};
+
+struct nouveau_oclass
+nve0_copy2_oclass = {
+ .handle = NV_ENGINE(COPY2, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_copy2_ctor,
+ .dtor = _nouveau_engine_dtor,
+ .init = _nouveau_engine_init,
+ .fini = _nouveau_engine_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h b/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
index 09962e4210e9..38676c74e6e0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
@@ -1,4 +1,4 @@
-static uint32_t nv98_pcrypt_data[] = {
+uint32_t nv98_pcrypt_data[] = {
/* 0x0000: ctx_dma */
/* 0x0000: ctx_dma_query */
0x00000000,
@@ -150,7 +150,7 @@ static uint32_t nv98_pcrypt_data[] = {
0x00000000,
};
-static uint32_t nv98_pcrypt_code[] = {
+uint32_t nv98_pcrypt_code[] = {
0x17f004bd,
0x0010fe35,
0xf10004fe,
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
index 5bc021f471f9..2551dafbec73 100644
--- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
@@ -141,13 +141,6 @@ nv84_crypt_intr(struct nouveau_subdev *subdev)
}
static int
-nv84_crypt_tlb_flush(struct nouveau_engine *engine)
-{
- nv50_vm_flush_engine(&engine->base, 0x0a);
- return 0;
-}
-
-static int
nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -165,7 +158,6 @@ nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv84_crypt_intr;
nv_engine(priv)->cclass = &nv84_crypt_cclass;
nv_engine(priv)->sclass = nv84_crypt_sclass;
- nv_engine(priv)->tlb_flush = nv84_crypt_tlb_flush;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
index 8bf8955051d4..c7082377ec76 100644
--- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
+++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
@@ -27,11 +27,11 @@
#include <core/enum.h>
#include <core/class.h>
#include <core/engctx.h>
-#include <core/falcon.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
+#include <engine/falcon.h>
#include <engine/fifo.h>
#include <engine/crypt.h>
@@ -119,13 +119,6 @@ nv98_crypt_intr(struct nouveau_subdev *subdev)
}
static int
-nv98_crypt_tlb_flush(struct nouveau_engine *engine)
-{
- nv50_vm_flush_engine(&engine->base, 0x0a);
- return 0;
-}
-
-static int
nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -143,7 +136,6 @@ nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv98_crypt_intr;
nv_engine(priv)->cclass = &nv98_crypt_cclass;
nv_engine(priv)->sclass = nv98_crypt_sclass;
- nv_engine(priv)->tlb_flush = nv98_crypt_tlb_flush;
nv_falcon(priv)->code.data = nv98_pcrypt_code;
nv_falcon(priv)->code.size = sizeof(nv98_pcrypt_code);
nv_falcon(priv)->data.data = nv98_pcrypt_data;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
index 5e8c3de75593..ffc18b80c5d9 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
@@ -227,9 +227,9 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
break;
@@ -279,9 +279,9 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
break;
@@ -305,9 +305,9 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
break;
@@ -319,7 +319,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -332,8 +332,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
@@ -346,7 +346,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -358,8 +358,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
@@ -372,7 +372,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -384,8 +384,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
@@ -398,7 +398,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -410,8 +410,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
index a36e64e98ef3..1df3578a5315 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
@@ -62,7 +62,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -91,7 +91,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -120,7 +120,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -148,7 +148,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -177,7 +177,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -206,7 +206,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -234,7 +234,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -263,7 +263,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
index a354e409cdff..4e6ef62e88c8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
@@ -62,7 +62,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -79,6 +79,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
@@ -91,7 +92,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -108,6 +109,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
@@ -120,7 +122,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
@@ -137,6 +139,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
@@ -149,7 +152,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 6a38402fa56c..8b42f45c2b1d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -34,9 +34,9 @@
#include <subdev/bios/disp.h>
#include <subdev/bios/init.h>
#include <subdev/bios/pll.h>
+#include <subdev/devinit.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
-#include <subdev/clock.h>
#include "nv50.h"
@@ -987,10 +987,10 @@ nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head)
static void
nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head)
{
- struct nouveau_clock *clk = nouveau_clock(priv);
+ struct nouveau_devinit *devinit = nouveau_devinit(priv);
u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
if (pclk)
- clk->pll_set(clk, PLL_VPLL0 + head, pclk);
+ devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
}
static void
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index 019eacd8a68f..52dd7a1db729 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -29,15 +29,14 @@
#include <engine/disp.h>
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <subdev/clock.h>
-
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/disp.h>
#include <subdev/bios/init.h>
#include <subdev/bios/pll.h>
+#include <subdev/devinit.h>
+#include <subdev/fb.h>
+#include <subdev/timer.h>
#include "nv50.h"
@@ -738,10 +737,10 @@ nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head)
static void
nvd0_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head)
{
- struct nouveau_clock *clk = nouveau_clock(priv);
+ struct nouveau_devinit *devinit = nouveau_devinit(priv);
u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
if (pclk)
- clk->pll_set(clk, PLL_VPLL0 + head, pclk);
+ devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000);
}
@@ -959,6 +958,9 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int heads = nv_rd32(parent, 0x022448);
int ret;
+ if (nv_rd32(parent, 0x022500) & 0x00000001)
+ return -ENODEV;
+
ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv);
*pobject = nv_object(priv);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
index 20725b363d58..fb1fe6ae5e74 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
@@ -54,6 +54,9 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int heads = nv_rd32(parent, 0x022448);
int ret;
+ if (nv_rd32(parent, 0x022500) & 0x00000001)
+ return -ENODEV;
+
ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv);
*pobject = nv_object(priv);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
index a488c36e40f9..42aa6b97dbea 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
@@ -54,6 +54,9 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int heads = nv_rd32(parent, 0x022448);
int ret;
+ if (nv_rd32(parent, 0x022500) & 0x00000001)
+ return -ENODEV;
+
ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv);
*pobject = nv_object(priv);
diff --git a/drivers/gpu/drm/nouveau/core/core/falcon.c b/drivers/gpu/drm/nouveau/core/engine/falcon.c
index e05c15777588..3c7a31f7590e 100644
--- a/drivers/gpu/drm/nouveau/core/core/falcon.c
+++ b/drivers/gpu/drm/nouveau/core/engine/falcon.c
@@ -20,8 +20,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
#include <subdev/timer.h>
u32
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
index 2b1f91721225..5c7433d5069f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
@@ -320,7 +320,7 @@ nv40_fifo_init(struct nouveau_object *object)
break;
default:
nv_wr32(priv, 0x002230, 0x00000000);
- nv_wr32(priv, 0x002220, ((pfb->ram.size - 512 * 1024 +
+ nv_wr32(priv, 0x002220, ((pfb->ram->size - 512 * 1024 +
priv->ramfc->addr) >> 16) |
0x00030000);
break;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
index 35b94bd18808..7f53196cff52 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
@@ -56,7 +56,9 @@ nv84_fifo_context_attach(struct nouveau_object *parent,
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : addr = 0x0020; break;
+ case NVDEV_ENGINE_VP : addr = 0x0040; break;
case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
+ case NVDEV_ENGINE_BSP : addr = 0x0080; break;
case NVDEV_ENGINE_CRYPT: addr = 0x00a0; break;
case NVDEV_ENGINE_COPY0: addr = 0x00c0; break;
default:
@@ -89,7 +91,9 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : engn = 0; addr = 0x0020; break;
+ case NVDEV_ENGINE_VP : engn = 3; addr = 0x0040; break;
case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break;
+ case NVDEV_ENGINE_BSP : engn = 5; addr = 0x0080; break;
case NVDEV_ENGINE_CRYPT: engn = 4; addr = 0x00a0; break;
case NVDEV_ENGINE_COPY0: engn = 2; addr = 0x00c0; break;
default:
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index 56192a7242ae..0338e66bc620 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -44,7 +44,8 @@ static const struct {
u64 subdev;
u64 mask;
} fifo_engine[] = {
- _(NVDEV_ENGINE_GR , (1ULL << NVDEV_ENGINE_SW)),
+ _(NVDEV_ENGINE_GR , (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_COPY2)),
_(NVDEV_ENGINE_VP , 0),
_(NVDEV_ENGINE_PPP , 0),
_(NVDEV_ENGINE_BSP , 0),
@@ -96,18 +97,6 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine)
mutex_lock(&nv_subdev(priv)->mutex);
cur = engn->playlist[engn->cur_playlist];
- if (unlikely(cur == NULL)) {
- int ret = nouveau_gpuobj_new(nv_object(priv), NULL,
- 0x8000, 0x1000, 0, &cur);
- if (ret) {
- mutex_unlock(&nv_subdev(priv)->mutex);
- nv_error(priv, "playlist alloc failed\n");
- return;
- }
-
- engn->playlist[engn->cur_playlist] = cur;
- }
-
engn->cur_playlist = !engn->cur_playlist;
for (i = 0, p = 0; i < priv->base.max; i++) {
@@ -138,10 +127,12 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
int ret;
switch (nv_engidx(object->engine)) {
- case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR :
+ case NVDEV_ENGINE_SW :
case NVDEV_ENGINE_COPY0:
- case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
+ case NVDEV_ENGINE_COPY1:
+ case NVDEV_ENGINE_COPY2:
+ return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
case NVDEV_ENGINE_BSP : addr = 0x0270; break;
case NVDEV_ENGINE_VP : addr = 0x0250; break;
case NVDEV_ENGINE_PPP : addr = 0x0260; break;
@@ -176,9 +167,10 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR :
case NVDEV_ENGINE_COPY0:
- case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
+ case NVDEV_ENGINE_COPY1:
+ case NVDEV_ENGINE_COPY2: addr = 0x0000; break;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
case NVDEV_ENGINE_BSP : addr = 0x0270; break;
case NVDEV_ENGINE_VP : addr = 0x0250; break;
case NVDEV_ENGINE_PPP : addr = 0x0260; break;
@@ -194,9 +186,12 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
return -EBUSY;
}
- nv_wo32(base, addr + 0x00, 0x00000000);
- nv_wo32(base, addr + 0x04, 0x00000000);
- bar->flush(bar);
+ if (addr) {
+ nv_wo32(base, addr + 0x00, 0x00000000);
+ nv_wo32(base, addr + 0x04, 0x00000000);
+ bar->flush(bar);
+ }
+
return 0;
}
@@ -592,13 +587,25 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_object **pobject)
{
struct nve0_fifo_priv *priv;
- int ret;
+ int ret, i;
ret = nouveau_fifo_create(parent, engine, oclass, 0, 4095, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
+ for (i = 0; i < FIFO_ENGINE_NR; i++) {
+ ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
+ 0, &priv->engine[i].playlist[0]);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
+ 0, &priv->engine[i].playlist[1]);
+ if (ret)
+ return ret;
+ }
+
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
if (ret)
@@ -629,7 +636,7 @@ nve0_fifo_dtor(struct nouveau_object *object)
nouveau_gpuobj_unmap(&priv->user.bar);
nouveau_gpuobj_ref(NULL, &priv->user.mem);
- for (i = 0; i < ARRAY_SIZE(priv->engine); i++) {
+ for (i = 0; i < FIFO_ENGINE_NR; i++) {
nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[1]);
nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[0]);
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
index 4cc6269d4077..3be7b950eece 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
@@ -1323,8 +1323,6 @@ nvc0_grctx_generate_9097(struct nvc0_graph_priv *priv)
nv_mthd(priv, 0x9097, 0x1450, 0x00300008);
nv_mthd(priv, 0x9097, 0x1454, 0x04000080);
nv_mthd(priv, 0x9097, 0x0214, 0x00000000);
- /* in trace, right after 0x90c0, not here */
- nv_mthd(priv, 0x9097, 0x3410, 0x80002006);
}
static void
@@ -1417,6 +1415,8 @@ nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv)
for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
nv_mthd(priv, 0x90c0, 0x2710 + (i * 0x40), 0x00014000);
nv_mthd(priv, 0x90c0, 0x2730 + (i * 0x40), 0x00014000);
+ }
+ for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
nv_mthd(priv, 0x90c0, 0x2714 + (i * 0x40), 0x00000040);
nv_mthd(priv, 0x90c0, 0x2734 + (i * 0x40), 0x00000040);
}
@@ -1456,7 +1456,23 @@ nvc0_grctx_generate_dispatch(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404020, 0x00000000);
nv_wr32(priv, 0x404024, 0x00000000);
nv_wr32(priv, 0x404028, 0x00000000);
- nv_wr32(priv, 0x40402c, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x40402c, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x404044, 0x00000000);
nv_wr32(priv, 0x404094, 0x00000000);
nv_wr32(priv, 0x404098, 0x00000000);
@@ -1472,6 +1488,7 @@ nvc0_grctx_generate_dispatch(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x4040c0, 0x00000000);
nv_wr32(priv, 0x4040c4, 0x00000000);
nv_wr32(priv, 0x4040c8, 0xf0000087);
+ nv_wr32(priv, 0x4040d0, 0x00000000);
nv_wr32(priv, 0x4040d4, 0x00000000);
nv_wr32(priv, 0x4040d8, 0x00000000);
nv_wr32(priv, 0x4040dc, 0x00000000);
@@ -1487,7 +1504,23 @@ nvc0_grctx_generate_dispatch(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404158, 0x00000200);
nv_wr32(priv, 0x404164, 0x00000055);
nv_wr32(priv, 0x404168, 0x00000000);
- nv_wr32(priv, 0x404174, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x404174, 0x00000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x404178, 0x00000000);
nv_wr32(priv, 0x40417c, 0x00000000);
for (i = 0; i < 8; i++)
@@ -1613,20 +1646,31 @@ nvc0_grctx_generate_unk47xx(struct nvc0_graph_priv *priv)
static void
nvc0_grctx_generate_shaders(struct nvc0_graph_priv *priv)
{
-
- if (nv_device(priv)->chipset >= 0xd0) {
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
nv_wr32(priv, 0x405800, 0x0f8000bf);
nv_wr32(priv, 0x405830, 0x02180218);
- nv_wr32(priv, 0x405834, 0x08000000);
- } else
- if (nv_device(priv)->chipset == 0xc1) {
+ nv_wr32(priv, 0x405834, 0x00000000);
+ break;
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x405800, 0x0f8000bf);
nv_wr32(priv, 0x405830, 0x02180218);
- nv_wr32(priv, 0x405834, 0x00000000);
- } else {
+ nv_wr32(priv, 0x405834, 0x08000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x405800, 0x078000bf);
nv_wr32(priv, 0x405830, 0x02180000);
nv_wr32(priv, 0x405834, 0x00000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
}
nv_wr32(priv, 0x405838, 0x00000000);
nv_wr32(priv, 0x405854, 0x00000000);
@@ -1657,12 +1701,24 @@ nvc0_grctx_generate_unk64xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x4064ac, 0x00003fff);
nv_wr32(priv, 0x4064b4, 0x00000000);
nv_wr32(priv, 0x4064b8, 0x00000000);
- if (nv_device(priv)->chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x4064bc, 0x00000000);
- if (nv_device(priv)->chipset == 0xc1 ||
- nv_device(priv)->chipset >= 0xd0) {
nv_wr32(priv, 0x4064c0, 0x80140078);
nv_wr32(priv, 0x4064c4, 0x0086ffff);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
}
}
@@ -1695,46 +1751,87 @@ nvc0_grctx_generate_ccache(struct nvc0_graph_priv *priv)
static void
nvc0_grctx_generate_rop(struct nvc0_graph_priv *priv)
{
- int chipset = nv_device(priv)->chipset;
-
/* ROPC_BROADCAST */
nv_wr32(priv, 0x408800, 0x02802a3c);
nv_wr32(priv, 0x408804, 0x00000040);
- if (chipset >= 0xd0) {
- nv_wr32(priv, 0x408808, 0x1043e005);
+ switch (nv_device(priv)->chipset) {
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x408808, 0x0003e00d);
nv_wr32(priv, 0x408900, 0x3080b801);
- nv_wr32(priv, 0x408904, 0x1043e005);
- nv_wr32(priv, 0x408908, 0x00c8102f);
- } else
- if (chipset == 0xc1) {
+ nv_wr32(priv, 0x408904, 0x02000001);
+ nv_wr32(priv, 0x408908, 0x00c80929);
+ break;
+ case 0xc1:
nv_wr32(priv, 0x408808, 0x1003e005);
nv_wr32(priv, 0x408900, 0x3080b801);
nv_wr32(priv, 0x408904, 0x62000001);
nv_wr32(priv, 0x408908, 0x00c80929);
- } else {
- nv_wr32(priv, 0x408808, 0x0003e00d);
+ break;
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x408808, 0x1043e005);
nv_wr32(priv, 0x408900, 0x3080b801);
- nv_wr32(priv, 0x408904, 0x02000001);
- nv_wr32(priv, 0x408908, 0x00c80929);
+ nv_wr32(priv, 0x408904, 0x1043e005);
+ nv_wr32(priv, 0x408908, 0x00c8102f);
+ break;
+ default:
+ BUG_ON(1);
+ break;
}
- nv_wr32(priv, 0x40890c, 0x00000000);
nv_wr32(priv, 0x408980, 0x0000011d);
}
static void
nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
{
- int chipset = nv_device(priv)->chipset;
int i;
/* GPC_BROADCAST */
nv_wr32(priv, 0x418380, 0x00000016);
nv_wr32(priv, 0x418400, 0x38004e00);
nv_wr32(priv, 0x418404, 0x71e0ffff);
- nv_wr32(priv, 0x418408, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x418408, 0x00000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x41840c, 0x00001008);
nv_wr32(priv, 0x418410, 0x0fff0fff);
- nv_wr32(priv, 0x418414, chipset < 0xd0 ? 0x00200fff : 0x02200fff);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418414, 0x02200fff);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x418414, 0x00200fff);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x418450, 0x00000000);
nv_wr32(priv, 0x418454, 0x00000000);
nv_wr32(priv, 0x418458, 0x00000000);
@@ -1749,17 +1846,65 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418700, 0x00000002);
nv_wr32(priv, 0x418704, 0x00000080);
nv_wr32(priv, 0x418708, 0x00000000);
- nv_wr32(priv, 0x41870c, chipset < 0xd0 ? 0x07c80000 : 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x41870c, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x41870c, 0x07c80000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x418710, 0x00000000);
- nv_wr32(priv, 0x418800, chipset < 0xd0 ? 0x0006860a : 0x7006860a);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418800, 0x7006860a);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x418800, 0x0006860a);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x418808, 0x00000000);
nv_wr32(priv, 0x41880c, 0x00000000);
nv_wr32(priv, 0x418810, 0x00000000);
nv_wr32(priv, 0x418828, 0x00008442);
- if (chipset == 0xc1 || chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x418830, 0x10000001);
- else
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x418830, 0x00000001);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x4188d8, 0x00000008);
nv_wr32(priv, 0x4188e0, 0x01000000);
nv_wr32(priv, 0x4188e8, 0x00000000);
@@ -1767,12 +1912,26 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x4188f0, 0x00000000);
nv_wr32(priv, 0x4188f4, 0x00000000);
nv_wr32(priv, 0x4188f8, 0x00000000);
- if (chipset >= 0xd0)
- nv_wr32(priv, 0x4188fc, 0x20100008);
- else if (chipset == 0xc1)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
nv_wr32(priv, 0x4188fc, 0x00100018);
- else
+ break;
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x4188fc, 0x20100008);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x4188fc, 0x00100000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x41891c, 0x00ff00ff);
nv_wr32(priv, 0x418924, 0x00000000);
nv_wr32(priv, 0x418928, 0x00ffff00);
@@ -1786,7 +1945,24 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418a14 + (i * 0x20), 0x00000000);
nv_wr32(priv, 0x418a18 + (i * 0x20), 0x00000000);
}
- nv_wr32(priv, 0x418b00, chipset < 0xd0 ? 0x00000000 : 0x00000006);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418b00, 0x00000006);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x418b00, 0x00000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x418b08, 0x0a418820);
nv_wr32(priv, 0x418b0c, 0x062080e6);
nv_wr32(priv, 0x418b10, 0x020398a4);
@@ -1803,8 +1979,23 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418c24, 0x00000000);
nv_wr32(priv, 0x418c28, 0x00000000);
nv_wr32(priv, 0x418c2c, 0x00000000);
- if (chipset == 0xc1 || chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x418c6c, 0x00000001);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x418c80, 0x20200004);
nv_wr32(priv, 0x418c8c, 0x00000001);
nv_wr32(priv, 0x419000, 0x00000780);
@@ -1816,16 +2007,28 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
static void
nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
{
- int chipset = nv_device(priv)->chipset;
-
/* GPC_BROADCAST.TP_BROADCAST */
nv_wr32(priv, 0x419818, 0x00000000);
nv_wr32(priv, 0x41983c, 0x00038bc7);
nv_wr32(priv, 0x419848, 0x00000000);
- if (chipset == 0xc1 || chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x419864, 0x00000129);
- else
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x419864, 0x0000012a);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x419888, 0x00000000);
nv_wr32(priv, 0x419a00, 0x000001f0);
nv_wr32(priv, 0x419a04, 0x00000001);
@@ -1833,12 +2036,43 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x419a0c, 0x00020000);
nv_wr32(priv, 0x419a10, 0x00000000);
nv_wr32(priv, 0x419a14, 0x00000200);
- nv_wr32(priv, 0x419a1c, 0x00000000);
- nv_wr32(priv, 0x419a20, 0x00000800);
- if (chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc0:
+ break;
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419a1c, 0x00000000);
+ nv_wr32(priv, 0x419a20, 0x00000800);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ switch (nv_device(priv)->chipset) {
+ case 0xc0:
+ case 0xc8:
+ break;
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x00419ac4, 0x0017f440);
- else if (chipset != 0xc0 && chipset != 0xc8)
+ break;
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x00419ac4, 0x0007f440);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x419b00, 0x0a418820);
nv_wr32(priv, 0x419b04, 0x062080e6);
nv_wr32(priv, 0x419b08, 0x020398a4);
@@ -1846,34 +2080,106 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x419b10, 0x0a418820);
nv_wr32(priv, 0x419b14, 0x000000e6);
nv_wr32(priv, 0x419bd0, 0x00900103);
- if (chipset == 0xc1 || chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x419be0, 0x00400001);
- else
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x419be0, 0x00000001);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x419be4, 0x00000000);
- nv_wr32(priv, 0x419c00, chipset < 0xd0 ? 0x00000002 : 0x0000000a);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419c00, 0x0000000a);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x419c00, 0x00000002);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x419c04, 0x00000006);
nv_wr32(priv, 0x419c08, 0x00000002);
nv_wr32(priv, 0x419c20, 0x00000000);
- if (nv_device(priv)->chipset >= 0xd0) {
+ switch (nv_device(priv)->chipset) {
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x419cb0, 0x00020048);
+ break;
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x419c24, 0x00084210);
nv_wr32(priv, 0x419c28, 0x3cf3cf3c);
nv_wr32(priv, 0x419cb0, 0x00020048);
- } else
- if (chipset == 0xce || chipset == 0xcf) {
- nv_wr32(priv, 0x419cb0, 0x00020048);
- } else {
+ break;
+ case 0xc0:
+ case 0xc8:
nv_wr32(priv, 0x419cb0, 0x00060048);
+ break;
+ default:
+ BUG_ON(1);
+ break;
}
nv_wr32(priv, 0x419ce8, 0x00000000);
nv_wr32(priv, 0x419cf4, 0x00000183);
- if (chipset == 0xc1 || chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x419d20, 0x12180000);
- else
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x419d20, 0x02180000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x419d24, 0x00001fff);
- if (chipset == 0xc1 || chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xd9:
+ case 0xd7:
nv_wr32(priv, 0x419d44, 0x02180218);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_wr32(priv, 0x419e04, 0x00000000);
nv_wr32(priv, 0x419e08, 0x00000000);
nv_wr32(priv, 0x419e0c, 0x00000000);
@@ -1899,12 +2205,55 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x419e8c, 0x00000000);
nv_wr32(priv, 0x419e90, 0x00000000);
nv_wr32(priv, 0x419e98, 0x00000000);
- if (chipset != 0xc0 && chipset != 0xc8)
+ switch (nv_device(priv)->chipset) {
+ case 0xc0:
+ case 0xc8:
+ break;
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419ee0, 0x00010110);
+ break;
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
nv_wr32(priv, 0x419ee0, 0x00011110);
- nv_wr32(priv, 0x419f50, 0x00000000);
- nv_wr32(priv, 0x419f54, 0x00000000);
- if (chipset != 0xc0 && chipset != 0xc8)
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ switch (nv_device(priv)->chipset) {
+ case 0xc0:
+ case 0xc8:
+ nv_wr32(priv, 0x419f50, 0x00000000);
+ nv_wr32(priv, 0x419f54, 0x00000000);
+ break;
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419f30, 0x00000000);
+ nv_wr32(priv, 0x419f34, 0x00000000);
+ nv_wr32(priv, 0x419f38, 0x00000000);
+ nv_wr32(priv, 0x419f3c, 0x00000000);
+ nv_wr32(priv, 0x419f40, 0x00000000);
+ nv_wr32(priv, 0x419f44, 0x00000000);
+ nv_wr32(priv, 0x419f48, 0x00000000);
+ nv_wr32(priv, 0x419f4c, 0x00000000);
+ nv_wr32(priv, 0x419f50, 0x00000000);
+ nv_wr32(priv, 0x419f54, 0x00000000);
nv_wr32(priv, 0x419f58, 0x00000000);
+ break;
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
}
int
@@ -1952,32 +2301,46 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
mmio_list(0x419008, 0x00000000, 0, 0);
mmio_list(0x418808, 0x00000000, 8, 0);
mmio_list(0x41880c, 0x80000018, 0, 0);
- if (nv_device(priv)->chipset != 0xc1) {
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xd9:
+ case 0xd7:
tmp = 0x02180000;
- mmio_list(0x405830, tmp, 0, 0);
+ mmio_list(0x405830, 0x00000218 | tmp, 0, 0);
+ mmio_list(0x4064c4, 0x0086ffff, 0, 0);
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
u32 reg = TPC_UNIT(gpc, tpc, 0x0520);
+ mmio_list(reg, 0x10000000 | tmp, 0, 0);
+ tmp += 0x0324;
+ }
+ for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+ u32 reg = TPC_UNIT(gpc, tpc, 0x0544);
mmio_list(reg, tmp, 0, 0);
tmp += 0x0324;
}
}
- } else {
+ break;
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
tmp = 0x02180000;
- mmio_list(0x405830, 0x00000218 | tmp, 0, 0);
- mmio_list(0x4064c4, 0x0086ffff, 0, 0);
+ mmio_list(0x405830, tmp, 0, 0);
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
u32 reg = TPC_UNIT(gpc, tpc, 0x0520);
- mmio_list(reg, 0x10000000 | tmp, 0, 0);
- tmp += 0x0324;
- }
- for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
- u32 reg = TPC_UNIT(gpc, tpc, 0x0544);
mmio_list(reg, tmp, 0, 0);
tmp += 0x0324;
}
}
+ break;
+ default:
+ BUG_ON(1);
+ break;
}
for (tpc = 0, id = 0; tpc < 4; tpc++) {
@@ -2209,9 +2572,23 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x00000215, 0x00000040);
nv_icmd(priv, 0x00000216, 0x00000040);
nv_icmd(priv, 0x00000217, 0x00000040);
- if (nv_device(priv)->chipset >= 0xd0) {
- for (i = 0x0400; i <= 0x0417; i++)
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ for (i = 0x400; i <= 0x417; i++)
nv_icmd(priv, i, 0x00000040);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
}
nv_icmd(priv, 0x00000218, 0x0000c080);
nv_icmd(priv, 0x00000219, 0x0000c080);
@@ -2221,9 +2598,23 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x0000021d, 0x0000c080);
nv_icmd(priv, 0x0000021e, 0x0000c080);
nv_icmd(priv, 0x0000021f, 0x0000c080);
- if (nv_device(priv)->chipset >= 0xd0) {
- for (i = 0x0440; i <= 0x0457; i++)
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ for (i = 0x440; i <= 0x457; i++)
nv_icmd(priv, i, 0x0000c080);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
}
nv_icmd(priv, 0x000000ad, 0x0000013e);
nv_icmd(priv, 0x000000e1, 0x00000010);
@@ -2787,9 +3178,23 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x0000053f, 0xffff0000);
nv_icmd(priv, 0x00000585, 0x0000003f);
nv_icmd(priv, 0x00000576, 0x00000003);
- if (nv_device(priv)->chipset == 0xc1 ||
- nv_device(priv)->chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xc1:
+ case 0xc8:
+ case 0xd9:
+ case 0xd7:
nv_icmd(priv, 0x0000057b, 0x00000059);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_icmd(priv, 0x00000586, 0x00000040);
nv_icmd(priv, 0x00000582, 0x00000080);
nv_icmd(priv, 0x00000583, 0x00000080);
@@ -2890,8 +3295,23 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x00000957, 0x00000003);
nv_icmd(priv, 0x0000095e, 0x20164010);
nv_icmd(priv, 0x0000095f, 0x00000020);
- if (nv_device(priv)->chipset >= 0xd0)
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ case 0xc8:
nv_icmd(priv, 0x0000097d, 0x00000020);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
nv_icmd(priv, 0x00000683, 0x00000006);
nv_icmd(priv, 0x00000685, 0x003fffff);
nv_icmd(priv, 0x00000687, 0x00000c48);
@@ -3020,6 +3440,8 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x00000825, 0x00000100);
nv_icmd(priv, 0x00000826, 0x00000001);
nv_icmd(priv, 0x0001e100, 0x00000001);
+
+
nv_wr32(priv, 0x400208, 0x00000000);
nv_wr32(priv, 0x404154, 0x00000400);
@@ -3032,6 +3454,25 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
nvc0_grctx_generate_9039(priv);
nvc0_grctx_generate_90c0(priv);
+ switch (nv_device(priv)->chipset) {
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_mthd(priv, 0x902d, 0x3410, 0x00000000);
+ break;
+ case 0xd9:
+ case 0xd7:
+ nv_mthd(priv, 0x902d, 0x3410, 0x80002006);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+
nv_wr32(priv, 0x000260, r000260);
return nvc0_grctx_fini(&info);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
index ae27dae3fe38..848570b4c519 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
@@ -749,31 +749,6 @@ nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x000841, 0x08000080);
nv_icmd(priv, 0x000842, 0x00400008);
nv_icmd(priv, 0x000843, 0x08000080);
- nv_icmd(priv, 0x000818, 0x00000000);
- nv_icmd(priv, 0x000819, 0x00000000);
- nv_icmd(priv, 0x00081a, 0x00000000);
- nv_icmd(priv, 0x00081b, 0x00000000);
- nv_icmd(priv, 0x00081c, 0x00000000);
- nv_icmd(priv, 0x00081d, 0x00000000);
- nv_icmd(priv, 0x00081e, 0x00000000);
- nv_icmd(priv, 0x00081f, 0x00000000);
- nv_icmd(priv, 0x000848, 0x00000000);
- nv_icmd(priv, 0x000849, 0x00000000);
- nv_icmd(priv, 0x00084a, 0x00000000);
- nv_icmd(priv, 0x00084b, 0x00000000);
- nv_icmd(priv, 0x00084c, 0x00000000);
- nv_icmd(priv, 0x00084d, 0x00000000);
- nv_icmd(priv, 0x00084e, 0x00000000);
- nv_icmd(priv, 0x00084f, 0x00000000);
- nv_icmd(priv, 0x000850, 0x00000000);
- nv_icmd(priv, 0x000851, 0x00000000);
- nv_icmd(priv, 0x000852, 0x00000000);
- nv_icmd(priv, 0x000853, 0x00000000);
- nv_icmd(priv, 0x000854, 0x00000000);
- nv_icmd(priv, 0x000855, 0x00000000);
- nv_icmd(priv, 0x000856, 0x00000000);
- nv_icmd(priv, 0x000857, 0x00000000);
- nv_icmd(priv, 0x000738, 0x00000000);
nv_icmd(priv, 0x0006aa, 0x00000001);
nv_icmd(priv, 0x0006ab, 0x00000002);
nv_icmd(priv, 0x0006ac, 0x00000080);
@@ -862,31 +837,6 @@ nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x000813, 0x00000006);
nv_icmd(priv, 0x000814, 0x00000008);
nv_icmd(priv, 0x000957, 0x00000003);
- nv_icmd(priv, 0x000818, 0x00000000);
- nv_icmd(priv, 0x000819, 0x00000000);
- nv_icmd(priv, 0x00081a, 0x00000000);
- nv_icmd(priv, 0x00081b, 0x00000000);
- nv_icmd(priv, 0x00081c, 0x00000000);
- nv_icmd(priv, 0x00081d, 0x00000000);
- nv_icmd(priv, 0x00081e, 0x00000000);
- nv_icmd(priv, 0x00081f, 0x00000000);
- nv_icmd(priv, 0x000848, 0x00000000);
- nv_icmd(priv, 0x000849, 0x00000000);
- nv_icmd(priv, 0x00084a, 0x00000000);
- nv_icmd(priv, 0x00084b, 0x00000000);
- nv_icmd(priv, 0x00084c, 0x00000000);
- nv_icmd(priv, 0x00084d, 0x00000000);
- nv_icmd(priv, 0x00084e, 0x00000000);
- nv_icmd(priv, 0x00084f, 0x00000000);
- nv_icmd(priv, 0x000850, 0x00000000);
- nv_icmd(priv, 0x000851, 0x00000000);
- nv_icmd(priv, 0x000852, 0x00000000);
- nv_icmd(priv, 0x000853, 0x00000000);
- nv_icmd(priv, 0x000854, 0x00000000);
- nv_icmd(priv, 0x000855, 0x00000000);
- nv_icmd(priv, 0x000856, 0x00000000);
- nv_icmd(priv, 0x000857, 0x00000000);
- nv_icmd(priv, 0x000738, 0x00000000);
nv_icmd(priv, 0x000b07, 0x00000002);
nv_icmd(priv, 0x000b08, 0x00000100);
nv_icmd(priv, 0x000b09, 0x00000100);
@@ -2162,12 +2112,30 @@ nve0_grctx_generate_902d(struct nvc0_graph_priv *priv)
nv_mthd(priv, 0x902d, 0x0244, 0x00000080);
nv_mthd(priv, 0x902d, 0x0248, 0x00000100);
nv_mthd(priv, 0x902d, 0x024c, 0x00000100);
- nv_mthd(priv, 0x902d, 0x3410, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xe6:
+ nv_mthd(priv, 0x902d, 0x3410, 0x80002006);
+ break;
+ case 0xe4:
+ case 0xe7:
+ default:
+ nv_mthd(priv, 0x902d, 0x3410, 0x00000000);
+ break;
+ }
}
static void
nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
{
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x404004, 0x00000000);
+ nv_wr32(priv, 0x404008, 0x00000000);
+ nv_wr32(priv, 0x40400c, 0x00000000);
+ break;
+ default:
+ break;
+ }
nv_wr32(priv, 0x404010, 0x0);
nv_wr32(priv, 0x404014, 0x0);
nv_wr32(priv, 0x404018, 0x0);
@@ -2175,6 +2143,19 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404020, 0x0);
nv_wr32(priv, 0x404024, 0xe000);
nv_wr32(priv, 0x404028, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x40402c, 0x00000000);
+ nv_wr32(priv, 0x404030, 0x00000000);
+ nv_wr32(priv, 0x404034, 0x00000000);
+ nv_wr32(priv, 0x404038, 0x00000000);
+ nv_wr32(priv, 0x40403c, 0x00000000);
+ nv_wr32(priv, 0x404040, 0x00000000);
+ nv_wr32(priv, 0x404044, 0x00000000);
+ break;
+ default:
+ break;
+ }
nv_wr32(priv, 0x4040a8, 0x0);
nv_wr32(priv, 0x4040ac, 0x0);
nv_wr32(priv, 0x4040b0, 0x0);
@@ -2192,6 +2173,22 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x4040e4, 0x0);
nv_wr32(priv, 0x4040e8, 0x1000);
nv_wr32(priv, 0x4040f8, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x404100, 0x00000000);
+ nv_wr32(priv, 0x404104, 0x00000000);
+ nv_wr32(priv, 0x404108, 0x00000000);
+ nv_wr32(priv, 0x40410c, 0x00000000);
+ nv_wr32(priv, 0x404110, 0x00000000);
+ nv_wr32(priv, 0x404114, 0x00000000);
+ nv_wr32(priv, 0x404118, 0x00000000);
+ nv_wr32(priv, 0x40411c, 0x00000000);
+ nv_wr32(priv, 0x404120, 0x00000000);
+ nv_wr32(priv, 0x404124, 0x00000000);
+ break;
+ default:
+ break;
+ }
nv_wr32(priv, 0x404130, 0x0);
nv_wr32(priv, 0x404134, 0x0);
nv_wr32(priv, 0x404138, 0x20000040);
@@ -2199,14 +2196,32 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404154, 0x400);
nv_wr32(priv, 0x404158, 0x200);
nv_wr32(priv, 0x404164, 0x55);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x40417c, 0x00000000);
+ nv_wr32(priv, 0x404180, 0x00000000);
+ break;
+ default:
+ break;
+ }
nv_wr32(priv, 0x4041a0, 0x0);
nv_wr32(priv, 0x4041a4, 0x0);
nv_wr32(priv, 0x4041a8, 0x0);
nv_wr32(priv, 0x4041ac, 0x0);
- nv_wr32(priv, 0x404200, 0x0);
- nv_wr32(priv, 0x404204, 0x0);
- nv_wr32(priv, 0x404208, 0x0);
- nv_wr32(priv, 0x40420c, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x404200, 0xa197);
+ nv_wr32(priv, 0x404204, 0xa1c0);
+ nv_wr32(priv, 0x404208, 0xa140);
+ nv_wr32(priv, 0x40420c, 0x902d);
+ break;
+ default:
+ nv_wr32(priv, 0x404200, 0x0);
+ nv_wr32(priv, 0x404204, 0x0);
+ nv_wr32(priv, 0x404208, 0x0);
+ nv_wr32(priv, 0x40420c, 0x0);
+ break;
+ }
}
static void
@@ -2224,7 +2239,13 @@ nve0_graph_generate_unk44xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404428, 0x0);
nv_wr32(priv, 0x40442c, 0x0);
nv_wr32(priv, 0x404430, 0x0);
- nv_wr32(priv, 0x404434, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ break;
+ default:
+ nv_wr32(priv, 0x404434, 0x0);
+ break;
+ }
nv_wr32(priv, 0x404438, 0x0);
nv_wr32(priv, 0x404460, 0x0);
nv_wr32(priv, 0x404464, 0x0);
@@ -2310,14 +2331,33 @@ nve0_graph_generate_unk58xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x405a00, 0x0);
nv_wr32(priv, 0x405a04, 0x0);
nv_wr32(priv, 0x405a18, 0x0);
+}
+
+static void
+nve0_graph_generate_unk5bxx(struct nvc0_graph_priv *priv)
+{
nv_wr32(priv, 0x405b00, 0x0);
nv_wr32(priv, 0x405b10, 0x1000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x405b20, 0x04000000);
+ break;
+ default:
+ break;
+ }
}
static void
nve0_graph_generate_unk60xx(struct nvc0_graph_priv *priv)
{
- nv_wr32(priv, 0x406020, 0x4103c1);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x406020, 0x34103c1);
+ break;
+ default:
+ nv_wr32(priv, 0x406020, 0x4103c1);
+ break;
+ }
nv_wr32(priv, 0x406028, 0x1);
nv_wr32(priv, 0x40602c, 0x1);
nv_wr32(priv, 0x406030, 0x1);
@@ -2329,11 +2369,27 @@ nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv)
{
nv_wr32(priv, 0x4064a8, 0x0);
nv_wr32(priv, 0x4064ac, 0x3fff);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x4064b0, 0x0);
+ break;
+ default:
+ break;
+ }
nv_wr32(priv, 0x4064b4, 0x0);
nv_wr32(priv, 0x4064b8, 0x0);
- nv_wr32(priv, 0x4064c0, 0x801a00f0);
- nv_wr32(priv, 0x4064c4, 0x192ffff);
- nv_wr32(priv, 0x4064c8, 0x1800600);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x4064c0, 0x802000f0);
+ nv_wr32(priv, 0x4064c4, 0x192ffff);
+ nv_wr32(priv, 0x4064c8, 0x18007c0);
+ break;
+ default:
+ nv_wr32(priv, 0x4064c0, 0x801a00f0);
+ nv_wr32(priv, 0x4064c4, 0x192ffff);
+ nv_wr32(priv, 0x4064c8, 0x1800600);
+ break;
+ }
nv_wr32(priv, 0x4064cc, 0x0);
nv_wr32(priv, 0x4064d0, 0x0);
nv_wr32(priv, 0x4064d4, 0x0);
@@ -2349,7 +2405,13 @@ nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv)
static void
nve0_graph_generate_unk70xx(struct nvc0_graph_priv *priv)
{
- nv_wr32(priv, 0x407040, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ break;
+ default:
+ nv_wr32(priv, 0x407040, 0x0);
+ break;
+ }
}
static void
@@ -2381,9 +2443,23 @@ nve0_graph_generate_unk80xx(struct nvc0_graph_priv *priv)
static void
nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv)
{
- nv_wr32(priv, 0x408800, 0x2802a3c);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x408800, 0x12802a3c);
+ break;
+ default:
+ nv_wr32(priv, 0x408800, 0x2802a3c);
+ break;
+ }
nv_wr32(priv, 0x408804, 0x40);
- nv_wr32(priv, 0x408808, 0x1043e005);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x408808, 0x1003e005);
+ break;
+ default:
+ nv_wr32(priv, 0x408808, 0x1043e005);
+ break;
+ }
nv_wr32(priv, 0x408840, 0xb);
nv_wr32(priv, 0x408900, 0x3080b801);
nv_wr32(priv, 0x408904, 0x62000001);
@@ -2394,6 +2470,8 @@ nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv)
static void
nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
{
+ int i;
+
nv_wr32(priv, 0x418380, 0x16);
nv_wr32(priv, 0x418400, 0x38004e00);
nv_wr32(priv, 0x418404, 0x71e0ffff);
@@ -2418,7 +2496,14 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418710, 0x0);
nv_wr32(priv, 0x418800, 0x7006860a);
nv_wr32(priv, 0x418808, 0x0);
- nv_wr32(priv, 0x41880c, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x41880c, 0x30);
+ break;
+ default:
+ nv_wr32(priv, 0x41880c, 0x0);
+ break;
+ }
nv_wr32(priv, 0x418810, 0x0);
nv_wr32(priv, 0x418828, 0x44);
nv_wr32(priv, 0x418830, 0x10000001);
@@ -2434,62 +2519,15 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418924, 0x0);
nv_wr32(priv, 0x418928, 0xffff00);
nv_wr32(priv, 0x41892c, 0xff00);
- nv_wr32(priv, 0x418a00, 0x0);
- nv_wr32(priv, 0x418a04, 0x0);
- nv_wr32(priv, 0x418a08, 0x0);
- nv_wr32(priv, 0x418a0c, 0x10000);
- nv_wr32(priv, 0x418a10, 0x0);
- nv_wr32(priv, 0x418a14, 0x0);
- nv_wr32(priv, 0x418a18, 0x0);
- nv_wr32(priv, 0x418a20, 0x0);
- nv_wr32(priv, 0x418a24, 0x0);
- nv_wr32(priv, 0x418a28, 0x0);
- nv_wr32(priv, 0x418a2c, 0x10000);
- nv_wr32(priv, 0x418a30, 0x0);
- nv_wr32(priv, 0x418a34, 0x0);
- nv_wr32(priv, 0x418a38, 0x0);
- nv_wr32(priv, 0x418a40, 0x0);
- nv_wr32(priv, 0x418a44, 0x0);
- nv_wr32(priv, 0x418a48, 0x0);
- nv_wr32(priv, 0x418a4c, 0x10000);
- nv_wr32(priv, 0x418a50, 0x0);
- nv_wr32(priv, 0x418a54, 0x0);
- nv_wr32(priv, 0x418a58, 0x0);
- nv_wr32(priv, 0x418a60, 0x0);
- nv_wr32(priv, 0x418a64, 0x0);
- nv_wr32(priv, 0x418a68, 0x0);
- nv_wr32(priv, 0x418a6c, 0x10000);
- nv_wr32(priv, 0x418a70, 0x0);
- nv_wr32(priv, 0x418a74, 0x0);
- nv_wr32(priv, 0x418a78, 0x0);
- nv_wr32(priv, 0x418a80, 0x0);
- nv_wr32(priv, 0x418a84, 0x0);
- nv_wr32(priv, 0x418a88, 0x0);
- nv_wr32(priv, 0x418a8c, 0x10000);
- nv_wr32(priv, 0x418a90, 0x0);
- nv_wr32(priv, 0x418a94, 0x0);
- nv_wr32(priv, 0x418a98, 0x0);
- nv_wr32(priv, 0x418aa0, 0x0);
- nv_wr32(priv, 0x418aa4, 0x0);
- nv_wr32(priv, 0x418aa8, 0x0);
- nv_wr32(priv, 0x418aac, 0x10000);
- nv_wr32(priv, 0x418ab0, 0x0);
- nv_wr32(priv, 0x418ab4, 0x0);
- nv_wr32(priv, 0x418ab8, 0x0);
- nv_wr32(priv, 0x418ac0, 0x0);
- nv_wr32(priv, 0x418ac4, 0x0);
- nv_wr32(priv, 0x418ac8, 0x0);
- nv_wr32(priv, 0x418acc, 0x10000);
- nv_wr32(priv, 0x418ad0, 0x0);
- nv_wr32(priv, 0x418ad4, 0x0);
- nv_wr32(priv, 0x418ad8, 0x0);
- nv_wr32(priv, 0x418ae0, 0x0);
- nv_wr32(priv, 0x418ae4, 0x0);
- nv_wr32(priv, 0x418ae8, 0x0);
- nv_wr32(priv, 0x418aec, 0x10000);
- nv_wr32(priv, 0x418af0, 0x0);
- nv_wr32(priv, 0x418af4, 0x0);
- nv_wr32(priv, 0x418af8, 0x0);
+ for (i = 0; i < 8; i++) {
+ nv_wr32(priv, 0x418a00 + (i * 0x20), 0x0);
+ nv_wr32(priv, 0x418a04 + (i * 0x20), 0x0);
+ nv_wr32(priv, 0x418a08 + (i * 0x20), 0x0);
+ nv_wr32(priv, 0x418a0c + (i * 0x20), 0x10000);
+ nv_wr32(priv, 0x418a10 + (i * 0x20), 0x0);
+ nv_wr32(priv, 0x418a14 + (i * 0x20), 0x0);
+ nv_wr32(priv, 0x418a18 + (i * 0x20), 0x0);
+ }
nv_wr32(priv, 0x418b00, 0x6);
nv_wr32(priv, 0x418b08, 0xa418820);
nv_wr32(priv, 0x418b0c, 0x62080e6);
@@ -2511,6 +2549,13 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418c6c, 0x1);
nv_wr32(priv, 0x418c80, 0x20200004);
nv_wr32(priv, 0x418c8c, 0x1);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x418d24, 0x0);
+ break;
+ default:
+ break;
+ }
nv_wr32(priv, 0x419000, 0x780);
nv_wr32(priv, 0x419004, 0x0);
nv_wr32(priv, 0x419008, 0x0);
@@ -2530,31 +2575,71 @@ nve0_graph_generate_tpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x419a10, 0x0);
nv_wr32(priv, 0x419a14, 0x200);
nv_wr32(priv, 0x419a1c, 0xc000);
- nv_wr32(priv, 0x419a20, 0x800);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419a20, 0x20800);
+ break;
+ default:
+ nv_wr32(priv, 0x419a20, 0x800);
+ break;
+ }
nv_wr32(priv, 0x419a30, 0x1);
nv_wr32(priv, 0x419ac4, 0x37f440);
- nv_wr32(priv, 0x419c00, 0xa);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419c00, 0x1a);
+ break;
+ default:
+ nv_wr32(priv, 0x419c00, 0xa);
+ break;
+ }
nv_wr32(priv, 0x419c04, 0x80000006);
nv_wr32(priv, 0x419c08, 0x2);
nv_wr32(priv, 0x419c20, 0x0);
nv_wr32(priv, 0x419c24, 0x84210);
nv_wr32(priv, 0x419c28, 0x3efbefbe);
nv_wr32(priv, 0x419ce8, 0x0);
- nv_wr32(priv, 0x419cf4, 0x3203);
- nv_wr32(priv, 0x419e04, 0x0);
- nv_wr32(priv, 0x419e08, 0x0);
- nv_wr32(priv, 0x419e0c, 0x0);
- nv_wr32(priv, 0x419e10, 0x402);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419cf4, 0x203);
+ nv_wr32(priv, 0x419e04, 0x0);
+ nv_wr32(priv, 0x419e08, 0x1d);
+ nv_wr32(priv, 0x419e0c, 0x0);
+ nv_wr32(priv, 0x419e10, 0x1c02);
+
+ break;
+ default:
+ nv_wr32(priv, 0x419cf4, 0x3203);
+ nv_wr32(priv, 0x419e04, 0x0);
+ nv_wr32(priv, 0x419e08, 0x0);
+ nv_wr32(priv, 0x419e0c, 0x0);
+ nv_wr32(priv, 0x419e10, 0x402);
+ break;
+ }
nv_wr32(priv, 0x419e44, 0x13eff2);
nv_wr32(priv, 0x419e48, 0x0);
nv_wr32(priv, 0x419e4c, 0x7f);
nv_wr32(priv, 0x419e50, 0x0);
nv_wr32(priv, 0x419e54, 0x0);
- nv_wr32(priv, 0x419e58, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419e58, 0x1);
+ break;
+ default:
+ nv_wr32(priv, 0x419e58, 0x0);
+ break;
+ }
nv_wr32(priv, 0x419e5c, 0x0);
nv_wr32(priv, 0x419e60, 0x0);
nv_wr32(priv, 0x419e64, 0x0);
- nv_wr32(priv, 0x419e68, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419e68, 0x2);
+ break;
+ default:
+ nv_wr32(priv, 0x419e68, 0x0);
+ break;
+ }
nv_wr32(priv, 0x419e6c, 0x0);
nv_wr32(priv, 0x419e70, 0x0);
nv_wr32(priv, 0x419e74, 0x0);
@@ -2567,28 +2652,73 @@ nve0_graph_generate_tpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x419e90, 0x0);
nv_wr32(priv, 0x419e94, 0x0);
nv_wr32(priv, 0x419e98, 0x0);
- nv_wr32(priv, 0x419eac, 0x1fcf);
- nv_wr32(priv, 0x419eb0, 0xd3f);
+ switch (nv_device(priv)->chipset) {
+ case 0xe4:
+ case 0xe7:
+ case 0xe6:
+ nv_wr32(priv, 0x419eac, 0x1f8f);
+ nv_wr32(priv, 0x419eb0, 0xd3f);
+ break;
+ case 0xf0:
+ nv_wr32(priv, 0x419eac, 0x1fcf);
+ nv_wr32(priv, 0x419eb0, 0xdb00da0);
+ nv_wr32(priv, 0x419eb8, 0x0);
+ break;
+ }
nv_wr32(priv, 0x419ec8, 0x1304f);
nv_wr32(priv, 0x419f30, 0x0);
nv_wr32(priv, 0x419f34, 0x0);
nv_wr32(priv, 0x419f38, 0x0);
nv_wr32(priv, 0x419f3c, 0x0);
- nv_wr32(priv, 0x419f40, 0x0);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419f40, 0x18);
+ break;
+ default:
+ nv_wr32(priv, 0x419f40, 0x0);
+ break;
+ }
nv_wr32(priv, 0x419f44, 0x0);
nv_wr32(priv, 0x419f48, 0x0);
nv_wr32(priv, 0x419f4c, 0x0);
nv_wr32(priv, 0x419f58, 0x0);
- nv_wr32(priv, 0x419f78, 0xb);
+ switch (nv_device(priv)->chipset) {
+ case 0xe4:
+ case 0xe7:
+ case 0xe6:
+ nv_wr32(priv, 0x419f70, 0x0);
+ nv_wr32(priv, 0x419f78, 0xb);
+ nv_wr32(priv, 0x419f7c, 0x27a);
+ break;
+ case 0xf0:
+ nv_wr32(priv, 0x419f70, 0x7300);
+ nv_wr32(priv, 0x419f78, 0xeb);
+ nv_wr32(priv, 0x419f7c, 0x404);
+ break;
+ }
}
static void
nve0_graph_generate_tpcunk(struct nvc0_graph_priv *priv)
{
nv_wr32(priv, 0x41be24, 0x6);
- nv_wr32(priv, 0x41bec0, 0x12180000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x41bec0, 0x10000000);
+ break;
+ default:
+ nv_wr32(priv, 0x41bec0, 0x12180000);
+ break;
+ }
nv_wr32(priv, 0x41bec4, 0x37f7f);
- nv_wr32(priv, 0x41bee4, 0x6480430);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x41bee4, 0x0);
+ break;
+ default:
+ nv_wr32(priv, 0x41bee4, 0x6480430);
+ break;
+ }
nv_wr32(priv, 0x41bf00, 0xa418820);
nv_wr32(priv, 0x41bf04, 0x62080e6);
nv_wr32(priv, 0x41bf08, 0x20398a4);
@@ -2624,6 +2754,7 @@ nve0_grctx_generate(struct nvc0_graph_priv *priv)
nve0_graph_generate_unk46xx(priv);
nve0_graph_generate_unk47xx(priv);
nve0_graph_generate_unk58xx(priv);
+ nve0_graph_generate_unk5bxx(priv);
nve0_graph_generate_unk60xx(priv);
nve0_graph_generate_unk64xx(priv);
nve0_graph_generate_unk70xx(priv);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc
index e6b228844a32..da18885c559c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc
@@ -23,42 +23,7 @@
* Authors: Ben Skeggs
*/
-define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
-define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
-
-ifdef(`include_code', `
-// Error codes
-define(`E_BAD_COMMAND', 0x01)
-define(`E_CMD_OVERFLOW', 0x02)
-
-// Util macros to help with debugging ucode hangs etc
-define(`T_WAIT', 0)
-define(`T_MMCTX', 1)
-define(`T_STRWAIT', 2)
-define(`T_STRINIT', 3)
-define(`T_AUTO', 4)
-define(`T_CHAN', 5)
-define(`T_LOAD', 6)
-define(`T_SAVE', 7)
-define(`T_LCHAN', 8)
-define(`T_LCTXH', 9)
-
-define(`trace_set', `
- mov $r8 0x83c
- shl b32 $r8 6
- clear b32 $r9
- bset $r9 $1
- iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
-')
-
-define(`trace_clr', `
- mov $r8 0x85c
- shl b32 $r8 6
- clear b32 $r9
- bset $r9 $1
- iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
-')
-
+#ifdef INCLUDE_CODE
// queue_put - add request to queue
//
// In : $r13 queue pointer
@@ -178,27 +143,41 @@ watchdog_clear:
iowr I[$r8 + 0x000] $r0
ret
-// wait_done{z,o} - wait on FUC_DONE bit to become clear/set
+// wait_donez - wait on FUC_DONE bit to become clear
+//
+// In : $r10 bit to wait on
+//
+wait_donez:
+ trace_set(T_WAIT);
+ mov $r8 0x818
+ shl b32 $r8 6
+ iowr I[$r8 + 0x000] $r10
+ wait_donez_ne:
+ mov $r8 0x400
+ shl b32 $r8 6
+ iord $r8 I[$r8 + 0x000]
+ xbit $r8 $r8 $r10
+ bra ne #wait_donez_ne
+ trace_clr(T_WAIT)
+ ret
+
+// wait_doneo - wait on FUC_DONE bit to become set
//
// In : $r10 bit to wait on
//
-define(`wait_done', `
-$1:
+wait_doneo:
trace_set(T_WAIT);
mov $r8 0x818
shl b32 $r8 6
- iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit
- wait_done_$1:
+ iowr I[$r8 + 0x000] $r10
+ wait_doneo_e:
mov $r8 0x400
shl b32 $r8 6
- iord $r8 I[$r8 + 0x000] // DONE
+ iord $r8 I[$r8 + 0x000]
xbit $r8 $r8 $r10
- bra $2 #wait_done_$1
+ bra e #wait_doneo_e
trace_clr(T_WAIT)
ret
-')
-wait_done(wait_donez, ne)
-wait_done(wait_doneo, e)
// mmctx_size - determine size of a mmio list transfer
//
@@ -397,4 +376,4 @@ strand_ctx_init:
sub b32 $r15 $r14 $r15
trace_clr(T_STRINIT)
ret
-')
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc
new file mode 100644
index 000000000000..4770e8c99432
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc
@@ -0,0 +1,369 @@
+/* fuc microcode for nvc0 PGRAPH/GPC
+ *
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+/* TODO
+ * - bracket certain functions with scratch writes, useful for debugging
+ * - watchdog timer around ctx operations
+ */
+
+#ifdef INCLUDE_DATA
+gpc_id: .b32 0
+gpc_mmio_list_head: .b32 0
+gpc_mmio_list_tail: .b32 0
+
+tpc_count: .b32 0
+tpc_mask: .b32 0
+tpc_mmio_list_head: .b32 0
+tpc_mmio_list_tail: .b32 0
+
+cmd_queue: queue_init
+#endif
+
+#ifdef INCLUDE_CODE
+// reports an exception to the host
+//
+// In: $r15 error code (see nvc0.fuc)
+//
+error:
+ push $r14
+ mov $r14 -0x67ec // 0x9814
+ sethi $r14 0x400000
+ call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code
+ add b32 $r14 0x41c
+ mov $r15 1
+ call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET
+ pop $r14
+ ret
+
+// GPC fuc initialisation, executed by triggering ucode start, will
+// fall through to main loop after completion.
+//
+// Input:
+// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
+// CC_SCRATCH[1]: context base
+//
+// Output:
+// CC_SCRATCH[0]:
+// 31:31: set to signal completion
+// CC_SCRATCH[1]:
+// 31:0: GPC context size
+//
+init:
+ clear b32 $r0
+ mov $sp $r0
+
+ // enable fifo access
+ mov $r1 0x1200
+ mov $r2 2
+ iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
+
+ // setup i0 handler, and route all interrupts to it
+ mov $r1 #ih
+ mov $iv0 $r1
+ mov $r1 0x400
+ iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
+
+ // enable fifo interrupt
+ mov $r2 4
+ iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
+
+ // enable interrupts
+ bset $flags ie0
+
+ // figure out which GPC we are, and how many TPCs we have
+ mov $r1 0x608
+ shl b32 $r1 6
+ iord $r2 I[$r1 + 0x000] // UNITS
+ mov $r3 1
+ and $r2 0x1f
+ shl b32 $r3 $r2
+ sub b32 $r3 1
+ st b32 D[$r0 + #tpc_count] $r2
+ st b32 D[$r0 + #tpc_mask] $r3
+ add b32 $r1 0x400
+ iord $r2 I[$r1 + 0x000] // MYINDEX
+ st b32 D[$r0 + #gpc_id] $r2
+
+ // find context data for this chipset
+ mov $r2 0x800
+ shl b32 $r2 6
+ iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
+ mov $r1 #chipsets - 12
+ init_find_chipset:
+ add b32 $r1 12
+ ld b32 $r3 D[$r1 + 0x00]
+ cmpu b32 $r3 $r2
+ bra e #init_context
+ cmpu b32 $r3 0
+ bra ne #init_find_chipset
+ // unknown chipset
+ ret
+
+ // initialise context base, and size tracking
+ init_context:
+ mov $r2 0x800
+ shl b32 $r2 6
+ iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
+ clear b32 $r3 // track GPC context size here
+
+ // set mmctx base addresses now so we don't have to do it later,
+ // they don't currently ever change
+ mov $r4 0x700
+ shl b32 $r4 6
+ shr b32 $r5 $r2 8
+ iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE
+ iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE
+
+ // calculate GPC mmio context size, store the chipset-specific
+ // mmio list pointers somewhere we can get at them later without
+ // re-parsing the chipset list
+ clear b32 $r14
+ clear b32 $r15
+ ld b16 $r14 D[$r1 + 4]
+ ld b16 $r15 D[$r1 + 6]
+ st b16 D[$r0 + #gpc_mmio_list_head] $r14
+ st b16 D[$r0 + #gpc_mmio_list_tail] $r15
+ call #mmctx_size
+ add b32 $r2 $r15
+ add b32 $r3 $r15
+
+ // calculate per-TPC mmio context size, store the list pointers
+ ld b16 $r14 D[$r1 + 8]
+ ld b16 $r15 D[$r1 + 10]
+ st b16 D[$r0 + #tpc_mmio_list_head] $r14
+ st b16 D[$r0 + #tpc_mmio_list_tail] $r15
+ call #mmctx_size
+ ld b32 $r14 D[$r0 + #tpc_count]
+ mulu $r14 $r15
+ add b32 $r2 $r14
+ add b32 $r3 $r14
+
+ // round up base/size to 256 byte boundary (for strand SWBASE)
+ add b32 $r4 0x1300
+ shr b32 $r3 2
+ iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!?
+ shr b32 $r2 8
+ shr b32 $r3 6
+ add b32 $r2 1
+ add b32 $r3 1
+ shl b32 $r2 8
+ shl b32 $r3 8
+
+ // calculate size of strand context data
+ mov b32 $r15 $r2
+ call #strand_ctx_init
+ add b32 $r3 $r15
+
+ // save context size, and tell HUB we're done
+ mov $r1 0x800
+ shl b32 $r1 6
+ iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size
+ add b32 $r1 0x800
+ clear b32 $r2
+ bset $r2 31
+ iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
+
+// Main program loop, very simple, sleeps until woken up by the interrupt
+// handler, pulls a command from the queue and executes its handler
+//
+main:
+ bset $flags $p0
+ sleep $p0
+ mov $r13 #cmd_queue
+ call #queue_get
+ bra $p1 #main
+
+ // 0x0000-0x0003 are all context transfers
+ cmpu b32 $r14 0x04
+ bra nc #main_not_ctx_xfer
+ // fetch $flags and mask off $p1/$p2
+ mov $r1 $flags
+ mov $r2 0x0006
+ not b32 $r2
+ and $r1 $r2
+ // set $p1/$p2 according to transfer type
+ shl b32 $r14 1
+ or $r1 $r14
+ mov $flags $r1
+ // transfer context data
+ call #ctx_xfer
+ bra #main
+
+ main_not_ctx_xfer:
+ shl b32 $r15 $r14 16
+ or $r15 E_BAD_COMMAND
+ call #error
+ bra #main
+
+// interrupt handler
+ih:
+ push $r8
+ mov $r8 $flags
+ push $r8
+ push $r9
+ push $r10
+ push $r11
+ push $r13
+ push $r14
+ push $r15
+
+ // incoming fifo command?
+ iord $r10 I[$r0 + 0x200] // INTR
+ and $r11 $r10 0x00000004
+ bra e #ih_no_fifo
+ // queue incoming fifo command for later processing
+ mov $r11 0x1900
+ mov $r13 #cmd_queue
+ iord $r14 I[$r11 + 0x100] // FIFO_CMD
+ iord $r15 I[$r11 + 0x000] // FIFO_DATA
+ call #queue_put
+ add b32 $r11 0x400
+ mov $r14 1
+ iowr I[$r11 + 0x000] $r14 // FIFO_ACK
+
+ // ack, and wake up main()
+ ih_no_fifo:
+ iowr I[$r0 + 0x100] $r10 // INTR_ACK
+
+ pop $r15
+ pop $r14
+ pop $r13
+ pop $r11
+ pop $r10
+ pop $r9
+ pop $r8
+ mov $flags $r8
+ pop $r8
+ bclr $flags $p0
+ iret
+
+// Set this GPC's bit in HUB_BAR, used to signal completion of various
+// activities to the HUB fuc
+//
+hub_barrier_done:
+ mov $r15 1
+ ld b32 $r14 D[$r0 + #gpc_id]
+ shl b32 $r15 $r14
+ mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET
+ sethi $r14 0x400000
+ call #nv_wr32
+ ret
+
+// Disables various things, waits a bit, and re-enables them..
+//
+// Not sure how exactly this helps, perhaps "ENABLE" is not such a
+// good description for the bits we turn off? Anyways, without this,
+// funny things happen.
+//
+ctx_redswitch:
+ mov $r14 0x614
+ shl b32 $r14 6
+ mov $r15 0x020
+ iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER
+ mov $r15 8
+ ctx_redswitch_delay:
+ sub b32 $r15 1
+ bra ne #ctx_redswitch_delay
+ mov $r15 0xa20
+ iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER
+ ret
+
+// Transfer GPC context data between GPU and storage area
+//
+// In: $r15 context base address
+// $p1 clear on save, set on load
+// $p2 set if opposite direction done/will be done, so:
+// on save it means: "a load will follow this save"
+// on load it means: "a save preceeded this load"
+//
+ctx_xfer:
+ // set context base address
+ mov $r1 0xa04
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r15// MEM_BASE
+ bra not $p1 #ctx_xfer_not_load
+ call #ctx_redswitch
+ ctx_xfer_not_load:
+
+ // strands
+ mov $r1 0x4afc
+ sethi $r1 0x20000
+ mov $r2 0xc
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
+ call #strand_wait
+ mov $r2 0x47fc
+ sethi $r2 0x20000
+ iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
+ xbit $r2 $flags $p1
+ add b32 $r2 3
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
+
+ // mmio context
+ xbit $r10 $flags $p1 // direction
+ or $r10 2 // first
+ mov $r11 0x0000
+ sethi $r11 0x500000
+ ld b32 $r12 D[$r0 + #gpc_id]
+ shl b32 $r12 15
+ add b32 $r11 $r12 // base = NV_PGRAPH_GPCn
+ ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
+ ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
+ mov $r14 0 // not multi
+ call #mmctx_xfer
+
+ // per-TPC mmio context
+ xbit $r10 $flags $p1 // direction
+ or $r10 4 // last
+ mov $r11 0x4000
+ sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0
+ ld b32 $r12 D[$r0 + #gpc_id]
+ shl b32 $r12 15
+ add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0
+ ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
+ ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
+ ld b32 $r15 D[$r0 + #tpc_mask]
+ mov $r14 0x800 // stride = 0x800
+ call #mmctx_xfer
+
+ // wait for strands to finish
+ call #strand_wait
+
+ // if load, or a save without a load following, do some
+ // unknown stuff that's done after finishing a block of
+ // strand commands
+ bra $p1 #ctx_xfer_post
+ bra not $p2 #ctx_xfer_done
+ ctx_xfer_post:
+ mov $r1 0x4afc
+ sethi $r1 0x20000
+ mov $r2 0xd
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d
+ call #strand_wait
+
+ // mark completion in HUB's barrier
+ ctx_xfer_done:
+ call #hub_barrier_done
+ ret
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
index f7055af0f2a6..c2d9e59bb58f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
@@ -1,6 +1,5 @@
-/* fuc microcode for nvc0 PGRAPH/GPC
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,32 +19,17 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors: Ben Skeggs
- */
-
-/* To build:
- * m4 gpcnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o gpcnvc0.fuc.h
+ * Authors: Ben Skeggs <[email protected]>
*/
-/* TODO
- * - bracket certain functions with scratch writes, useful for debugging
- * - watchdog timer around ctx operations
- */
+#define NVGF
+#include "macros.fuc"
.section #nvc0_grgpc_data
-include(`nvc0.fuc')
-gpc_id: .b32 0
-gpc_mmio_list_head: .b32 0
-gpc_mmio_list_tail: .b32 0
-
-tpc_count: .b32 0
-tpc_mask: .b32 0
-tpc_mmio_list_head: .b32 0
-tpc_mmio_list_tail: .b32 0
-
-cmd_queue: queue_init
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "gpc.fuc"
-// chipset descriptions
chipsets:
.b8 0xc0 0 0 0
.b16 #nvc0_gpc_mmio_head
@@ -81,23 +65,26 @@ chipsets:
.b16 #nvc0_gpc_mmio_head
.b16 #nvc0_gpc_mmio_tail
.b16 #nvc0_tpc_mmio_head
-.b16 #nvcf_tpc_mmio_tail
+.b16 #nvc3_tpc_mmio_tail
.b8 0xd9 0 0 0
.b16 #nvd9_gpc_mmio_head
-.b16 #nvd9_gpc_mmio_tail
-.b16 #nvd9_tpc_mmio_head
+.b16 #nvc1_gpc_mmio_tail
+.b16 #nvc0_tpc_mmio_head
.b16 #nvd9_tpc_mmio_tail
.b8 0xd7 0 0 0
.b16 #nvd9_gpc_mmio_head
-.b16 #nvd9_gpc_mmio_tail
-.b16 #nvd9_tpc_mmio_head
+.b16 #nvc1_gpc_mmio_tail
+.b16 #nvc0_tpc_mmio_head
.b16 #nvd9_tpc_mmio_tail
.b8 0 0 0 0
// GPC mmio lists
nvc0_gpc_mmio_head:
+mmctx_data(0x000408, 1)
+nvd9_gpc_mmio_head:
mmctx_data(0x000380, 1)
-mmctx_data(0x000400, 6)
+mmctx_data(0x000400, 2);
+mmctx_data(0x00040c, 3);
mmctx_data(0x000450, 9)
mmctx_data(0x000600, 1)
mmctx_data(0x000684, 1)
@@ -124,35 +111,6 @@ nvc0_gpc_mmio_tail:
mmctx_data(0x000c6c, 1);
nvc1_gpc_mmio_tail:
-nvd9_gpc_mmio_head:
-mmctx_data(0x000380, 1)
-mmctx_data(0x000400, 2)
-mmctx_data(0x00040c, 3)
-mmctx_data(0x000450, 9)
-mmctx_data(0x000600, 1)
-mmctx_data(0x000684, 1)
-mmctx_data(0x000700, 5)
-mmctx_data(0x000800, 1)
-mmctx_data(0x000808, 3)
-mmctx_data(0x000828, 1)
-mmctx_data(0x000830, 1)
-mmctx_data(0x0008d8, 1)
-mmctx_data(0x0008e0, 1)
-mmctx_data(0x0008e8, 6)
-mmctx_data(0x00091c, 1)
-mmctx_data(0x000924, 3)
-mmctx_data(0x000b00, 1)
-mmctx_data(0x000b08, 6)
-mmctx_data(0x000bb8, 1)
-mmctx_data(0x000c08, 1)
-mmctx_data(0x000c10, 8)
-mmctx_data(0x000c6c, 1)
-mmctx_data(0x000c80, 1)
-mmctx_data(0x000c8c, 1)
-mmctx_data(0x001000, 3)
-mmctx_data(0x001014, 1)
-nvd9_gpc_mmio_tail:
-
// TPC mmio lists
nvc0_tpc_mmio_head:
mmctx_data(0x000018, 1)
@@ -161,7 +119,6 @@ mmctx_data(0x000048, 1)
mmctx_data(0x000064, 1)
mmctx_data(0x000088, 1)
mmctx_data(0x000200, 6)
-mmctx_data(0x00021c, 2)
mmctx_data(0x000300, 6)
mmctx_data(0x0003d0, 1)
mmctx_data(0x0003e0, 2)
@@ -176,369 +133,22 @@ mmctx_data(0x000644, 20)
mmctx_data(0x000698, 1)
mmctx_data(0x000750, 2)
nvc0_tpc_mmio_tail:
-mmctx_data(0x000758, 1)
+mmctx_data(0x00021c, 2)
mmctx_data(0x0002c4, 1)
-mmctx_data(0x0006e0, 1)
-nvcf_tpc_mmio_tail:
-mmctx_data(0x0004bc, 1)
+mmctx_data(0x000730, 8)
+mmctx_data(0x000758, 1)
nvc3_tpc_mmio_tail:
mmctx_data(0x000544, 1)
nvc1_tpc_mmio_tail:
-
-nvd9_tpc_mmio_head:
-mmctx_data(0x000018, 1)
-mmctx_data(0x00003c, 1)
-mmctx_data(0x000048, 1)
-mmctx_data(0x000064, 1)
-mmctx_data(0x000088, 1)
-mmctx_data(0x000200, 6)
-mmctx_data(0x00021c, 2)
-mmctx_data(0x0002c4, 1)
-mmctx_data(0x000300, 6)
-mmctx_data(0x0003d0, 1)
-mmctx_data(0x0003e0, 2)
-mmctx_data(0x000400, 3)
-mmctx_data(0x000420, 3)
-mmctx_data(0x0004b0, 1)
-mmctx_data(0x0004e8, 1)
-mmctx_data(0x0004f4, 1)
-mmctx_data(0x000520, 2)
-mmctx_data(0x000544, 1)
-mmctx_data(0x000604, 4)
-mmctx_data(0x000644, 20)
-mmctx_data(0x000698, 1)
-mmctx_data(0x0006e0, 1)
-mmctx_data(0x000750, 3)
+mmctx_data(0x000424, 2);
+mmctx_data(0x0006e0, 1);
nvd9_tpc_mmio_tail:
+#undef INCLUDE_DATA
.section #nvc0_grgpc_code
+#define INCLUDE_CODE
bra #init
-define(`include_code')
-include(`nvc0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nvc0.fuc)
-//
-error:
- push $r14
- mov $r14 -0x67ec // 0x9814
- sethi $r14 0x400000
- call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code
- add b32 $r14 0x41c
- mov $r15 1
- call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET
- pop $r14
- ret
-
-// GPC fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-// CC_SCRATCH[1]: context base
-//
-// Output:
-// CC_SCRATCH[0]:
-// 31:31: set to signal completion
-// CC_SCRATCH[1]:
-// 31:0: GPC context size
-//
-init:
- clear b32 $r0
- mov $sp $r0
-
- // enable fifo access
- mov $r1 0x1200
- mov $r2 2
- iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
-
- // setup i0 handler, and route all interrupts to it
- mov $r1 #ih
- mov $iv0 $r1
- mov $r1 0x400
- iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
-
- // enable fifo interrupt
- mov $r2 4
- iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
-
- // enable interrupts
- bset $flags ie0
-
- // figure out which GPC we are, and how many TPCs we have
- mov $r1 0x608
- shl b32 $r1 6
- iord $r2 I[$r1 + 0x000] // UNITS
- mov $r3 1
- and $r2 0x1f
- shl b32 $r3 $r2
- sub b32 $r3 1
- st b32 D[$r0 + #tpc_count] $r2
- st b32 D[$r0 + #tpc_mask] $r3
- add b32 $r1 0x400
- iord $r2 I[$r1 + 0x000] // MYINDEX
- st b32 D[$r0 + #gpc_id] $r2
-
- // find context data for this chipset
- mov $r2 0x800
- shl b32 $r2 6
- iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
- mov $r1 #chipsets - 12
- init_find_chipset:
- add b32 $r1 12
- ld b32 $r3 D[$r1 + 0x00]
- cmpu b32 $r3 $r2
- bra e #init_context
- cmpu b32 $r3 0
- bra ne #init_find_chipset
- // unknown chipset
- ret
-
- // initialise context base, and size tracking
- init_context:
- mov $r2 0x800
- shl b32 $r2 6
- iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
- clear b32 $r3 // track GPC context size here
-
- // set mmctx base addresses now so we don't have to do it later,
- // they don't currently ever change
- mov $r4 0x700
- shl b32 $r4 6
- shr b32 $r5 $r2 8
- iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE
- iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE
-
- // calculate GPC mmio context size, store the chipset-specific
- // mmio list pointers somewhere we can get at them later without
- // re-parsing the chipset list
- clear b32 $r14
- clear b32 $r15
- ld b16 $r14 D[$r1 + 4]
- ld b16 $r15 D[$r1 + 6]
- st b16 D[$r0 + #gpc_mmio_list_head] $r14
- st b16 D[$r0 + #gpc_mmio_list_tail] $r15
- call #mmctx_size
- add b32 $r2 $r15
- add b32 $r3 $r15
-
- // calculate per-TPC mmio context size, store the list pointers
- ld b16 $r14 D[$r1 + 8]
- ld b16 $r15 D[$r1 + 10]
- st b16 D[$r0 + #tpc_mmio_list_head] $r14
- st b16 D[$r0 + #tpc_mmio_list_tail] $r15
- call #mmctx_size
- ld b32 $r14 D[$r0 + #tpc_count]
- mulu $r14 $r15
- add b32 $r2 $r14
- add b32 $r3 $r14
-
- // round up base/size to 256 byte boundary (for strand SWBASE)
- add b32 $r4 0x1300
- shr b32 $r3 2
- iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!?
- shr b32 $r2 8
- shr b32 $r3 6
- add b32 $r2 1
- add b32 $r3 1
- shl b32 $r2 8
- shl b32 $r3 8
-
- // calculate size of strand context data
- mov b32 $r15 $r2
- call #strand_ctx_init
- add b32 $r3 $r15
-
- // save context size, and tell HUB we're done
- mov $r1 0x800
- shl b32 $r1 6
- iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size
- add b32 $r1 0x800
- clear b32 $r2
- bset $r2 31
- iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
- bset $flags $p0
- sleep $p0
- mov $r13 #cmd_queue
- call #queue_get
- bra $p1 #main
-
- // 0x0000-0x0003 are all context transfers
- cmpu b32 $r14 0x04
- bra nc #main_not_ctx_xfer
- // fetch $flags and mask off $p1/$p2
- mov $r1 $flags
- mov $r2 0x0006
- not b32 $r2
- and $r1 $r2
- // set $p1/$p2 according to transfer type
- shl b32 $r14 1
- or $r1 $r14
- mov $flags $r1
- // transfer context data
- call #ctx_xfer
- bra #main
-
- main_not_ctx_xfer:
- shl b32 $r15 $r14 16
- or $r15 E_BAD_COMMAND
- call #error
- bra #main
-
-// interrupt handler
-ih:
- push $r8
- mov $r8 $flags
- push $r8
- push $r9
- push $r10
- push $r11
- push $r13
- push $r14
- push $r15
-
- // incoming fifo command?
- iord $r10 I[$r0 + 0x200] // INTR
- and $r11 $r10 0x00000004
- bra e #ih_no_fifo
- // queue incoming fifo command for later processing
- mov $r11 0x1900
- mov $r13 #cmd_queue
- iord $r14 I[$r11 + 0x100] // FIFO_CMD
- iord $r15 I[$r11 + 0x000] // FIFO_DATA
- call #queue_put
- add b32 $r11 0x400
- mov $r14 1
- iowr I[$r11 + 0x000] $r14 // FIFO_ACK
-
- // ack, and wake up main()
- ih_no_fifo:
- iowr I[$r0 + 0x100] $r10 // INTR_ACK
-
- pop $r15
- pop $r14
- pop $r13
- pop $r11
- pop $r10
- pop $r9
- pop $r8
- mov $flags $r8
- pop $r8
- bclr $flags $p0
- iret
-
-// Set this GPC's bit in HUB_BAR, used to signal completion of various
-// activities to the HUB fuc
-//
-hub_barrier_done:
- mov $r15 1
- ld b32 $r14 D[$r0 + #gpc_id]
- shl b32 $r15 $r14
- mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET
- sethi $r14 0x400000
- call #nv_wr32
- ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off? Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
- mov $r14 0x614
- shl b32 $r14 6
- mov $r15 0x020
- iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER
- mov $r15 8
- ctx_redswitch_delay:
- sub b32 $r15 1
- bra ne #ctx_redswitch_delay
- mov $r15 0xa20
- iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER
- ret
-
-// Transfer GPC context data between GPU and storage area
-//
-// In: $r15 context base address
-// $p1 clear on save, set on load
-// $p2 set if opposite direction done/will be done, so:
-// on save it means: "a load will follow this save"
-// on load it means: "a save preceeded this load"
-//
-ctx_xfer:
- // set context base address
- mov $r1 0xa04
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r15// MEM_BASE
- bra not $p1 #ctx_xfer_not_load
- call #ctx_redswitch
- ctx_xfer_not_load:
-
- // strands
- mov $r1 0x4afc
- sethi $r1 0x20000
- mov $r2 0xc
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
- call #strand_wait
- mov $r2 0x47fc
- sethi $r2 0x20000
- iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
- xbit $r2 $flags $p1
- add b32 $r2 3
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
- // mmio context
- xbit $r10 $flags $p1 // direction
- or $r10 2 // first
- mov $r11 0x0000
- sethi $r11 0x500000
- ld b32 $r12 D[$r0 + #gpc_id]
- shl b32 $r12 15
- add b32 $r11 $r12 // base = NV_PGRAPH_GPCn
- ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
- ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
- mov $r14 0 // not multi
- call #mmctx_xfer
-
- // per-TPC mmio context
- xbit $r10 $flags $p1 // direction
- or $r10 4 // last
- mov $r11 0x4000
- sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0
- ld b32 $r12 D[$r0 + #gpc_id]
- shl b32 $r12 15
- add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0
- ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
- ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
- ld b32 $r15 D[$r0 + #tpc_mask]
- mov $r14 0x800 // stride = 0x800
- call #mmctx_xfer
-
- // wait for strands to finish
- call #strand_wait
-
- // if load, or a save without a load following, do some
- // unknown stuff that's done after finishing a block of
- // strand commands
- bra $p1 #ctx_xfer_post
- bra not $p2 #ctx_xfer_done
- ctx_xfer_post:
- mov $r1 0x4afc
- sethi $r1 0x20000
- mov $r2 0xd
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d
- call #strand_wait
-
- // mark completion in HUB's barrier
- ctx_xfer_done:
- call #hub_barrier_done
- ret
-
+#include "com.fuc"
+#include "gpc.fuc"
.align 256
+#undef INCLUDE_CODE
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
index 96050ddb22ca..66ec1acaadee 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
@@ -34,59 +34,36 @@ uint32_t nvc0_grgpc_data[] = {
0x00000000,
/* 0x0064: chipsets */
0x000000c0,
- 0x012800c8,
- 0x01e40194,
+ 0x013c00d4,
+ 0x018c0140,
0x000000c1,
- 0x012c00c8,
- 0x01f80194,
+ 0x014000d4,
+ 0x01a00140,
0x000000c3,
- 0x012800c8,
- 0x01f40194,
+ 0x013c00d4,
+ 0x019c0140,
0x000000c4,
- 0x012800c8,
- 0x01f40194,
+ 0x013c00d4,
+ 0x019c0140,
0x000000c8,
- 0x012800c8,
- 0x01e40194,
+ 0x013c00d4,
+ 0x018c0140,
0x000000ce,
- 0x012800c8,
- 0x01f40194,
+ 0x013c00d4,
+ 0x019c0140,
0x000000cf,
- 0x012800c8,
- 0x01f00194,
+ 0x013c00d4,
+ 0x019c0140,
0x000000d9,
- 0x0194012c,
- 0x025401f8,
- 0x00000000,
-/* 0x00c8: nvc0_gpc_mmio_head */
- 0x00000380,
- 0x14000400,
- 0x20000450,
- 0x00000600,
- 0x00000684,
- 0x10000700,
- 0x00000800,
- 0x08000808,
- 0x00000828,
- 0x00000830,
- 0x000008d8,
- 0x000008e0,
- 0x140008e8,
- 0x0000091c,
- 0x08000924,
- 0x00000b00,
- 0x14000b08,
- 0x00000bb8,
- 0x00000c08,
- 0x1c000c10,
- 0x00000c80,
- 0x00000c8c,
- 0x08001000,
- 0x00001014,
-/* 0x0128: nvc0_gpc_mmio_tail */
- 0x00000c6c,
-/* 0x012c: nvc1_gpc_mmio_tail */
-/* 0x012c: nvd9_gpc_mmio_head */
+ 0x014000d8,
+ 0x01a80140,
+ 0x000000d7,
+ 0x014000d8,
+ 0x01a80140,
+ 0x00000000,
+/* 0x00d4: nvc0_gpc_mmio_head */
+ 0x00000408,
+/* 0x00d8: nvd9_gpc_mmio_head */
0x00000380,
0x04000400,
0x0800040c,
@@ -108,20 +85,20 @@ uint32_t nvc0_grgpc_data[] = {
0x00000bb8,
0x00000c08,
0x1c000c10,
- 0x00000c6c,
0x00000c80,
0x00000c8c,
0x08001000,
0x00001014,
-/* 0x0194: nvd9_gpc_mmio_tail */
-/* 0x0194: nvc0_tpc_mmio_head */
+/* 0x013c: nvc0_gpc_mmio_tail */
+ 0x00000c6c,
+/* 0x0140: nvc1_gpc_mmio_tail */
+/* 0x0140: nvc0_tpc_mmio_head */
0x00000018,
0x0000003c,
0x00000048,
0x00000064,
0x00000088,
0x14000200,
- 0x0400021c,
0x14000300,
0x000003d0,
0x040003e0,
@@ -135,39 +112,16 @@ uint32_t nvc0_grgpc_data[] = {
0x4c000644,
0x00000698,
0x04000750,
-/* 0x01e4: nvc0_tpc_mmio_tail */
- 0x00000758,
- 0x000002c4,
- 0x000006e0,
-/* 0x01f0: nvcf_tpc_mmio_tail */
- 0x000004bc,
-/* 0x01f4: nvc3_tpc_mmio_tail */
- 0x00000544,
-/* 0x01f8: nvc1_tpc_mmio_tail */
-/* 0x01f8: nvd9_tpc_mmio_head */
- 0x00000018,
- 0x0000003c,
- 0x00000048,
- 0x00000064,
- 0x00000088,
- 0x14000200,
+/* 0x018c: nvc0_tpc_mmio_tail */
0x0400021c,
0x000002c4,
- 0x14000300,
- 0x000003d0,
- 0x040003e0,
- 0x08000400,
- 0x08000420,
- 0x000004b0,
- 0x000004e8,
- 0x000004f4,
- 0x04000520,
+ 0x1c000730,
+ 0x00000758,
+/* 0x019c: nvc3_tpc_mmio_tail */
0x00000544,
- 0x0c000604,
- 0x4c000644,
- 0x00000698,
+/* 0x01a0: nvc1_tpc_mmio_tail */
+ 0x04000424,
0x000006e0,
- 0x08000750,
};
uint32_t nvc0_grgpc_code[] = {
@@ -238,7 +192,7 @@ uint32_t nvc0_grgpc_code[] = {
0x0089d000,
0x081887f1,
0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
+/* 0x00e2: wait_donez_ne */
0x87f1008a,
0x84b60400,
0x0088cf06,
@@ -255,7 +209,7 @@ uint32_t nvc0_grgpc_code[] = {
0x87f10089,
0x84b60818,
0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x011c: wait_doneo_e */
0x040087f1,
0xcf0684b6,
0x8aff0088,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
index 62ab231cd6b6..2fc585eeff95 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
@@ -1,6 +1,5 @@
-/* fuc microcode for nve0 PGRAPH/GPC
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,32 +19,17 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors: Ben Skeggs
- */
-
-/* To build:
- * m4 nve0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grgpc.fuc.h
+ * Authors: Ben Skeggs <[email protected]>
*/
-/* TODO
- * - bracket certain functions with scratch writes, useful for debugging
- * - watchdog timer around ctx operations
- */
+#define NVGK
+#include "macros.fuc"
.section #nve0_grgpc_data
-include(`nve0.fuc')
-gpc_id: .b32 0
-gpc_mmio_list_head: .b32 0
-gpc_mmio_list_tail: .b32 0
-
-tpc_count: .b32 0
-tpc_mask: .b32 0
-tpc_mmio_list_head: .b32 0
-tpc_mmio_list_tail: .b32 0
-
-cmd_queue: queue_init
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "gpc.fuc"
-// chipset descriptions
chipsets:
.b8 0xe4 0 0 0
.b16 #nve4_gpc_mmio_head
@@ -62,6 +46,11 @@ chipsets:
.b16 #nve4_gpc_mmio_tail
.b16 #nve4_tpc_mmio_head
.b16 #nve4_tpc_mmio_tail
+.b8 0xf0 0 0 0
+.b16 #nvf0_gpc_mmio_head
+.b16 #nvf0_gpc_mmio_tail
+.b16 #nvf0_tpc_mmio_head
+.b16 #nvf0_tpc_mmio_tail
.b8 0 0 0 0
// GPC mmio lists
@@ -101,6 +90,37 @@ mmctx_data(0x0031d0, 1)
mmctx_data(0x0031e0, 2)
nve4_gpc_mmio_tail:
+nvf0_gpc_mmio_head:
+mmctx_data(0x000380, 1)
+mmctx_data(0x000400, 2)
+mmctx_data(0x00040c, 3)
+mmctx_data(0x000450, 9)
+mmctx_data(0x000600, 1)
+mmctx_data(0x000684, 1)
+mmctx_data(0x000700, 5)
+mmctx_data(0x000800, 1)
+mmctx_data(0x000808, 3)
+mmctx_data(0x000828, 1)
+mmctx_data(0x000830, 1)
+mmctx_data(0x0008d8, 1)
+mmctx_data(0x0008e0, 1)
+mmctx_data(0x0008e8, 6)
+mmctx_data(0x00091c, 1)
+mmctx_data(0x000924, 3)
+mmctx_data(0x000b00, 1)
+mmctx_data(0x000b08, 6)
+mmctx_data(0x000bb8, 1)
+mmctx_data(0x000c08, 1)
+mmctx_data(0x000c10, 8)
+mmctx_data(0x000c40, 1)
+mmctx_data(0x000c6c, 1)
+mmctx_data(0x000c80, 1)
+mmctx_data(0x000c8c, 1)
+mmctx_data(0x000d24, 1)
+mmctx_data(0x001000, 3)
+mmctx_data(0x001014, 1)
+nvf0_gpc_mmio_tail:
+
// TPC mmio lists
nve4_tpc_mmio_head:
mmctx_data(0x000048, 1)
@@ -120,337 +140,38 @@ mmctx_data(0x0006ac, 2)
mmctx_data(0x0006c8, 1)
mmctx_data(0x000730, 8)
mmctx_data(0x000758, 1)
-mmctx_data(0x000778, 1)
+mmctx_data(0x000770, 1)
+mmctx_data(0x000778, 2)
nve4_tpc_mmio_tail:
+nvf0_tpc_mmio_head:
+mmctx_data(0x000048, 1)
+mmctx_data(0x000064, 1)
+mmctx_data(0x000088, 1)
+mmctx_data(0x000200, 6)
+mmctx_data(0x00021c, 2)
+mmctx_data(0x000230, 1)
+mmctx_data(0x0002c4, 1)
+mmctx_data(0x000400, 3)
+mmctx_data(0x000420, 3)
+mmctx_data(0x0004e8, 1)
+mmctx_data(0x0004f4, 1)
+mmctx_data(0x000604, 4)
+mmctx_data(0x000644, 22)
+mmctx_data(0x0006ac, 2)
+mmctx_data(0x0006b8, 1)
+mmctx_data(0x0006c8, 1)
+mmctx_data(0x000730, 8)
+mmctx_data(0x000758, 1)
+mmctx_data(0x000770, 1)
+mmctx_data(0x000778, 2)
+nvf0_tpc_mmio_tail:
+#undef INCLUDE_DATA
+
.section #nve0_grgpc_code
+#define INCLUDE_CODE
bra #init
-define(`include_code')
-include(`nve0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nve0.fuc)
-//
-error:
- push $r14
- mov $r14 -0x67ec // 0x9814
- sethi $r14 0x400000
- call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code
- add b32 $r14 0x41c
- mov $r15 1
- call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET
- pop $r14
- ret
-
-// GPC fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-// CC_SCRATCH[1]: context base
-//
-// Output:
-// CC_SCRATCH[0]:
-// 31:31: set to signal completion
-// CC_SCRATCH[1]:
-// 31:0: GPC context size
-//
-init:
- clear b32 $r0
- mov $sp $r0
-
- // enable fifo access
- mov $r1 0x1200
- mov $r2 2
- iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
-
- // setup i0 handler, and route all interrupts to it
- mov $r1 #ih
- mov $iv0 $r1
- mov $r1 0x400
- iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
-
- // enable fifo interrupt
- mov $r2 4
- iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
-
- // enable interrupts
- bset $flags ie0
-
- // figure out which GPC we are, and how many TPCs we have
- mov $r1 0x608
- shl b32 $r1 6
- iord $r2 I[$r1 + 0x000] // UNITS
- mov $r3 1
- and $r2 0x1f
- shl b32 $r3 $r2
- sub b32 $r3 1
- st b32 D[$r0 + #tpc_count] $r2
- st b32 D[$r0 + #tpc_mask] $r3
- add b32 $r1 0x400
- iord $r2 I[$r1 + 0x000] // MYINDEX
- st b32 D[$r0 + #gpc_id] $r2
-
- // find context data for this chipset
- mov $r2 0x800
- shl b32 $r2 6
- iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
- mov $r1 #chipsets - 12
- init_find_chipset:
- add b32 $r1 12
- ld b32 $r3 D[$r1 + 0x00]
- cmpu b32 $r3 $r2
- bra e #init_context
- cmpu b32 $r3 0
- bra ne #init_find_chipset
- // unknown chipset
- ret
-
- // initialise context base, and size tracking
- init_context:
- mov $r2 0x800
- shl b32 $r2 6
- iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
- clear b32 $r3 // track GPC context size here
-
- // set mmctx base addresses now so we don't have to do it later,
- // they don't currently ever change
- mov $r4 0x700
- shl b32 $r4 6
- shr b32 $r5 $r2 8
- iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE
- iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE
-
- // calculate GPC mmio context size, store the chipset-specific
- // mmio list pointers somewhere we can get at them later without
- // re-parsing the chipset list
- clear b32 $r14
- clear b32 $r15
- ld b16 $r14 D[$r1 + 4]
- ld b16 $r15 D[$r1 + 6]
- st b16 D[$r0 + #gpc_mmio_list_head] $r14
- st b16 D[$r0 + #gpc_mmio_list_tail] $r15
- call #mmctx_size
- add b32 $r2 $r15
- add b32 $r3 $r15
-
- // calculate per-TPC mmio context size, store the list pointers
- ld b16 $r14 D[$r1 + 8]
- ld b16 $r15 D[$r1 + 10]
- st b16 D[$r0 + #tpc_mmio_list_head] $r14
- st b16 D[$r0 + #tpc_mmio_list_tail] $r15
- call #mmctx_size
- ld b32 $r14 D[$r0 + #tpc_count]
- mulu $r14 $r15
- add b32 $r2 $r14
- add b32 $r3 $r14
-
- // round up base/size to 256 byte boundary (for strand SWBASE)
- add b32 $r4 0x1300
- shr b32 $r3 2
- iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!?
- shr b32 $r2 8
- shr b32 $r3 6
- add b32 $r2 1
- add b32 $r3 1
- shl b32 $r2 8
- shl b32 $r3 8
-
- // calculate size of strand context data
- mov b32 $r15 $r2
- call #strand_ctx_init
- add b32 $r3 $r15
-
- // save context size, and tell HUB we're done
- mov $r1 0x800
- shl b32 $r1 6
- iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size
- add b32 $r1 0x800
- clear b32 $r2
- bset $r2 31
- iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
- bset $flags $p0
- sleep $p0
- mov $r13 #cmd_queue
- call #queue_get
- bra $p1 #main
-
- // 0x0000-0x0003 are all context transfers
- cmpu b32 $r14 0x04
- bra nc #main_not_ctx_xfer
- // fetch $flags and mask off $p1/$p2
- mov $r1 $flags
- mov $r2 0x0006
- not b32 $r2
- and $r1 $r2
- // set $p1/$p2 according to transfer type
- shl b32 $r14 1
- or $r1 $r14
- mov $flags $r1
- // transfer context data
- call #ctx_xfer
- bra #main
-
- main_not_ctx_xfer:
- shl b32 $r15 $r14 16
- or $r15 E_BAD_COMMAND
- call #error
- bra #main
-
-// interrupt handler
-ih:
- push $r8
- mov $r8 $flags
- push $r8
- push $r9
- push $r10
- push $r11
- push $r13
- push $r14
- push $r15
-
- // incoming fifo command?
- iord $r10 I[$r0 + 0x200] // INTR
- and $r11 $r10 0x00000004
- bra e #ih_no_fifo
- // queue incoming fifo command for later processing
- mov $r11 0x1900
- mov $r13 #cmd_queue
- iord $r14 I[$r11 + 0x100] // FIFO_CMD
- iord $r15 I[$r11 + 0x000] // FIFO_DATA
- call #queue_put
- add b32 $r11 0x400
- mov $r14 1
- iowr I[$r11 + 0x000] $r14 // FIFO_ACK
-
- // ack, and wake up main()
- ih_no_fifo:
- iowr I[$r0 + 0x100] $r10 // INTR_ACK
-
- pop $r15
- pop $r14
- pop $r13
- pop $r11
- pop $r10
- pop $r9
- pop $r8
- mov $flags $r8
- pop $r8
- bclr $flags $p0
- iret
-
-// Set this GPC's bit in HUB_BAR, used to signal completion of various
-// activities to the HUB fuc
-//
-hub_barrier_done:
- mov $r15 1
- ld b32 $r14 D[$r0 + #gpc_id]
- shl b32 $r15 $r14
- mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET
- sethi $r14 0x400000
- call #nv_wr32
- ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off? Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
- mov $r14 0x614
- shl b32 $r14 6
- mov $r15 0x020
- iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER
- mov $r15 8
- ctx_redswitch_delay:
- sub b32 $r15 1
- bra ne #ctx_redswitch_delay
- mov $r15 0xa20
- iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER
- ret
-
-// Transfer GPC context data between GPU and storage area
-//
-// In: $r15 context base address
-// $p1 clear on save, set on load
-// $p2 set if opposite direction done/will be done, so:
-// on save it means: "a load will follow this save"
-// on load it means: "a save preceeded this load"
-//
-ctx_xfer:
- // set context base address
- mov $r1 0xa04
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r15// MEM_BASE
- bra not $p1 #ctx_xfer_not_load
- call #ctx_redswitch
- ctx_xfer_not_load:
-
- // strands
- mov $r1 0x4afc
- sethi $r1 0x20000
- mov $r2 0xc
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
- call #strand_wait
- mov $r2 0x47fc
- sethi $r2 0x20000
- iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
- xbit $r2 $flags $p1
- add b32 $r2 3
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
- // mmio context
- xbit $r10 $flags $p1 // direction
- or $r10 2 // first
- mov $r11 0x0000
- sethi $r11 0x500000
- ld b32 $r12 D[$r0 + #gpc_id]
- shl b32 $r12 15
- add b32 $r11 $r12 // base = NV_PGRAPH_GPCn
- ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
- ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
- mov $r14 0 // not multi
- call #mmctx_xfer
-
- // per-TPC mmio context
- xbit $r10 $flags $p1 // direction
- or $r10 4 // last
- mov $r11 0x4000
- sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0
- ld b32 $r12 D[$r0 + #gpc_id]
- shl b32 $r12 15
- add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0
- ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
- ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
- ld b32 $r15 D[$r0 + #tpc_mask]
- mov $r14 0x800 // stride = 0x800
- call #mmctx_xfer
-
- // wait for strands to finish
- call #strand_wait
-
- // if load, or a save without a load following, do some
- // unknown stuff that's done after finishing a block of
- // strand commands
- bra $p1 #ctx_xfer_post
- bra not $p2 #ctx_xfer_done
- ctx_xfer_post:
- mov $r1 0x4afc
- sethi $r1 0x20000
- mov $r2 0xd
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d
- call #strand_wait
-
- // mark completion in HUB's barrier
- ctx_xfer_done:
- call #hub_barrier_done
- ret
-
+#include "com.fuc"
+#include "gpc.fuc"
.align 256
+#undef INCLUDE_CODE
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
index 09ee4702c8b2..504ae96cd3dd 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
@@ -34,16 +34,19 @@ uint32_t nve0_grgpc_data[] = {
0x00000000,
/* 0x0064: chipsets */
0x000000e4,
- 0x0110008c,
- 0x01580110,
+ 0x011c0098,
+ 0x01d8018c,
0x000000e7,
- 0x0110008c,
- 0x01580110,
+ 0x011c0098,
+ 0x01d8018c,
0x000000e6,
- 0x0110008c,
- 0x01580110,
+ 0x011c0098,
+ 0x01d8018c,
+ 0x000000f0,
+ 0x018c011c,
+ 0x022801d8,
0x00000000,
-/* 0x008c: nve4_gpc_mmio_head */
+/* 0x0098: nve4_gpc_mmio_head */
0x00000380,
0x04000400,
0x0800040c,
@@ -77,8 +80,59 @@ uint32_t nve0_grgpc_data[] = {
0x14003100,
0x000031d0,
0x040031e0,
-/* 0x0110: nve4_gpc_mmio_tail */
-/* 0x0110: nve4_tpc_mmio_head */
+/* 0x011c: nve4_gpc_mmio_tail */
+/* 0x011c: nvf0_gpc_mmio_head */
+ 0x00000380,
+ 0x04000400,
+ 0x0800040c,
+ 0x20000450,
+ 0x00000600,
+ 0x00000684,
+ 0x10000700,
+ 0x00000800,
+ 0x08000808,
+ 0x00000828,
+ 0x00000830,
+ 0x000008d8,
+ 0x000008e0,
+ 0x140008e8,
+ 0x0000091c,
+ 0x08000924,
+ 0x00000b00,
+ 0x14000b08,
+ 0x00000bb8,
+ 0x00000c08,
+ 0x1c000c10,
+ 0x00000c40,
+ 0x00000c6c,
+ 0x00000c80,
+ 0x00000c8c,
+ 0x00000d24,
+ 0x08001000,
+ 0x00001014,
+/* 0x018c: nvf0_gpc_mmio_tail */
+/* 0x018c: nve4_tpc_mmio_head */
+ 0x00000048,
+ 0x00000064,
+ 0x00000088,
+ 0x14000200,
+ 0x0400021c,
+ 0x00000230,
+ 0x000002c4,
+ 0x08000400,
+ 0x08000420,
+ 0x000004e8,
+ 0x000004f4,
+ 0x0c000604,
+ 0x54000644,
+ 0x040006ac,
+ 0x000006c8,
+ 0x1c000730,
+ 0x00000758,
+ 0x00000770,
+ 0x04000778,
+/* 0x01d8: nve4_tpc_mmio_tail */
+/* 0x01d8: nvf0_tpc_mmio_head */
0x00000048,
0x00000064,
0x00000088,
@@ -93,10 +147,12 @@ uint32_t nve0_grgpc_data[] = {
0x0c000604,
0x54000644,
0x040006ac,
+ 0x000006b8,
0x000006c8,
0x1c000730,
0x00000758,
- 0x00000778,
+ 0x00000770,
+ 0x04000778,
};
uint32_t nve0_grgpc_code[] = {
@@ -167,7 +223,7 @@ uint32_t nve0_grgpc_code[] = {
0x0089d000,
0x081887f1,
0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
+/* 0x00e2: wait_donez_ne */
0x87f1008a,
0x84b60400,
0x0088cf06,
@@ -184,7 +240,7 @@ uint32_t nve0_grgpc_code[] = {
0x87f10089,
0x84b60818,
0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x011c: wait_doneo_e */
0x040087f1,
0xcf0684b6,
0x8aff0088,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc
new file mode 100644
index 000000000000..5c68bf6d69aa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc
@@ -0,0 +1,755 @@
+/* fuc microcode for nvc0 PGRAPH/HUB
+ *
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#ifdef INCLUDE_DATA
+gpc_count: .b32 0
+rop_count: .b32 0
+cmd_queue: queue_init
+hub_mmio_list_head: .b32 0
+hub_mmio_list_tail: .b32 0
+
+ctx_current: .b32 0
+
+.align 256
+chan_data:
+chan_mmio_count: .b32 0
+chan_mmio_address: .b32 0
+
+.align 256
+xfer_data: .skip 256
+
+#endif
+
+#ifdef INCLUDE_CODE
+// reports an exception to the host
+//
+// In: $r15 error code (see nvc0.fuc)
+//
+error:
+ push $r14
+ mov $r14 0x814
+ shl b32 $r14 6
+ iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code
+ mov $r14 0xc1c
+ shl b32 $r14 6
+ mov $r15 1
+ iowr I[$r14 + 0x000] $r15 // INTR_UP_SET
+ pop $r14
+ ret
+
+// HUB fuc initialisation, executed by triggering ucode start, will
+// fall through to main loop after completion.
+//
+// Input:
+// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
+//
+// Output:
+// CC_SCRATCH[0]:
+// 31:31: set to signal completion
+// CC_SCRATCH[1]:
+// 31:0: total PGRAPH context size
+//
+init:
+ clear b32 $r0
+ mov $sp $r0
+ mov $xdbase $r0
+
+ // enable fifo access
+ mov $r1 0x1200
+ mov $r2 2
+ iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
+
+ // setup i0 handler, and route all interrupts to it
+ mov $r1 #ih
+ mov $iv0 $r1
+ mov $r1 0x400
+ iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
+
+ // route HUB_CHANNEL_SWITCH to fuc interrupt 8
+ mov $r3 0x404
+ shl b32 $r3 6
+ mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
+ iowr I[$r3 + 0x000] $r2
+
+ // not sure what these are, route them because NVIDIA does, and
+ // the IRQ handler will signal the host if we ever get one.. we
+ // may find out if/why we need to handle these if so..
+ //
+ mov $r2 0x2004
+ iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
+ mov $r2 0x200b
+ iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
+ mov $r2 0x200c
+ iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
+
+ // enable all INTR_UP interrupts
+ mov $r2 0xc24
+ shl b32 $r2 6
+ not b32 $r3 $r0
+ iowr I[$r2] $r3
+
+ // enable fifo, ctxsw, 9, 10, 15 interrupts
+ mov $r2 -0x78fc // 0x8704
+ sethi $r2 0
+ iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
+
+ // fifo level triggered, rest edge
+ sub b32 $r1 0x100
+ mov $r2 4
+ iowr I[$r1] $r2
+
+ // enable interrupts
+ bset $flags ie0
+
+ // fetch enabled GPC/ROP counts
+ mov $r14 -0x69fc // 0x409604
+ sethi $r14 0x400000
+ call #nv_rd32
+ extr $r1 $r15 16:20
+ st b32 D[$r0 + #rop_count] $r1
+ and $r15 0x1f
+ st b32 D[$r0 + #gpc_count] $r15
+
+ // set BAR_REQMASK to GPC mask
+ mov $r1 1
+ shl b32 $r1 $r15
+ sub b32 $r1 1
+ mov $r2 0x40c
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r1
+ iowr I[$r2 + 0x100] $r1
+
+ // find context data for this chipset
+ mov $r2 0x800
+ shl b32 $r2 6
+ iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
+ mov $r15 #chipsets - 8
+ init_find_chipset:
+ add b32 $r15 8
+ ld b32 $r3 D[$r15 + 0x00]
+ cmpu b32 $r3 $r2
+ bra e #init_context
+ cmpu b32 $r3 0
+ bra ne #init_find_chipset
+ // unknown chipset
+ ret
+
+ // context size calculation, reserve first 256 bytes for use by fuc
+ init_context:
+ mov $r1 256
+
+ // calculate size of mmio context data
+ ld b16 $r14 D[$r15 + 4]
+ ld b16 $r15 D[$r15 + 6]
+ sethi $r14 0
+ st b32 D[$r0 + #hub_mmio_list_head] $r14
+ st b32 D[$r0 + #hub_mmio_list_tail] $r15
+ call #mmctx_size
+
+ // set mmctx base addresses now so we don't have to do it later,
+ // they don't (currently) ever change
+ mov $r3 0x700
+ shl b32 $r3 6
+ shr b32 $r4 $r1 8
+ iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE
+ iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE
+ add b32 $r3 0x1300
+ add b32 $r1 $r15
+ shr b32 $r15 2
+ iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!?
+
+ // strands, base offset needs to be aligned to 256 bytes
+ shr b32 $r1 8
+ add b32 $r1 1
+ shl b32 $r1 8
+ mov b32 $r15 $r1
+ call #strand_ctx_init
+ add b32 $r1 $r15
+
+ // initialise each GPC in sequence by passing in the offset of its
+ // context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
+ // has previously been uploaded by the host) running.
+ //
+ // the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
+ // when it has completed, and return the size of its context data
+ // in GPCn_CC_SCRATCH[1]
+ //
+ ld b32 $r3 D[$r0 + #gpc_count]
+ mov $r4 0x2000
+ sethi $r4 0x500000
+ init_gpc:
+ // setup, and start GPC ucode running
+ add b32 $r14 $r4 0x804
+ mov b32 $r15 $r1
+ call #nv_wr32 // CC_SCRATCH[1] = ctx offset
+ add b32 $r14 $r4 0x800
+ mov b32 $r15 $r2
+ call #nv_wr32 // CC_SCRATCH[0] = chipset
+ add b32 $r14 $r4 0x10c
+ clear b32 $r15
+ call #nv_wr32
+ add b32 $r14 $r4 0x104
+ call #nv_wr32 // ENTRY
+ add b32 $r14 $r4 0x100
+ mov $r15 2 // CTRL_START_TRIGGER
+ call #nv_wr32 // CTRL
+
+ // wait for it to complete, and adjust context size
+ add b32 $r14 $r4 0x800
+ init_gpc_wait:
+ call #nv_rd32
+ xbit $r15 $r15 31
+ bra e #init_gpc_wait
+ add b32 $r14 $r4 0x804
+ call #nv_rd32
+ add b32 $r1 $r15
+
+ // next!
+ add b32 $r4 0x8000
+ sub b32 $r3 1
+ bra ne #init_gpc
+
+ // save context size, and tell host we're ready
+ mov $r2 0x800
+ shl b32 $r2 6
+ iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size
+ add b32 $r2 0x800
+ clear b32 $r1
+ bset $r1 31
+ iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000
+
+// Main program loop, very simple, sleeps until woken up by the interrupt
+// handler, pulls a command from the queue and executes its handler
+//
+main:
+ // sleep until we have something to do
+ bset $flags $p0
+ sleep $p0
+ mov $r13 #cmd_queue
+ call #queue_get
+ bra $p1 #main
+
+ // context switch, requested by GPU?
+ cmpu b32 $r14 0x4001
+ bra ne #main_not_ctx_switch
+ trace_set(T_AUTO)
+ mov $r1 0xb00
+ shl b32 $r1 6
+ iord $r2 I[$r1 + 0x100] // CHAN_NEXT
+ iord $r1 I[$r1 + 0x000] // CHAN_CUR
+
+ xbit $r3 $r1 31
+ bra e #chsw_no_prev
+ xbit $r3 $r2 31
+ bra e #chsw_prev_no_next
+ push $r2
+ mov b32 $r2 $r1
+ trace_set(T_SAVE)
+ bclr $flags $p1
+ bset $flags $p2
+ call #ctx_xfer
+ trace_clr(T_SAVE);
+ pop $r2
+ trace_set(T_LOAD);
+ bset $flags $p1
+ call #ctx_xfer
+ trace_clr(T_LOAD);
+ bra #chsw_done
+ chsw_prev_no_next:
+ push $r2
+ mov b32 $r2 $r1
+ bclr $flags $p1
+ bclr $flags $p2
+ call #ctx_xfer
+ pop $r2
+ mov $r1 0xb00
+ shl b32 $r1 6
+ iowr I[$r1] $r2
+ bra #chsw_done
+ chsw_no_prev:
+ xbit $r3 $r2 31
+ bra e #chsw_done
+ bset $flags $p1
+ bclr $flags $p2
+ call #ctx_xfer
+
+ // ack the context switch request
+ chsw_done:
+ mov $r1 0xb0c
+ shl b32 $r1 6
+ mov $r2 1
+ iowr I[$r1 + 0x000] $r2 // 0x409b0c
+ trace_clr(T_AUTO)
+ bra #main
+
+ // request to set current channel? (*not* a context switch)
+ main_not_ctx_switch:
+ cmpu b32 $r14 0x0001
+ bra ne #main_not_ctx_chan
+ mov b32 $r2 $r15
+ call #ctx_chan
+ bra #main_done
+
+ // request to store current channel context?
+ main_not_ctx_chan:
+ cmpu b32 $r14 0x0002
+ bra ne #main_not_ctx_save
+ trace_set(T_SAVE)
+ bclr $flags $p1
+ bclr $flags $p2
+ call #ctx_xfer
+ trace_clr(T_SAVE)
+ bra #main_done
+
+ main_not_ctx_save:
+ shl b32 $r15 $r14 16
+ or $r15 E_BAD_COMMAND
+ call #error
+ bra #main
+
+ main_done:
+ mov $r1 0x820
+ shl b32 $r1 6
+ clear b32 $r2
+ bset $r2 31
+ iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
+ bra #main
+
+// interrupt handler
+ih:
+ push $r8
+ mov $r8 $flags
+ push $r8
+ push $r9
+ push $r10
+ push $r11
+ push $r13
+ push $r14
+ push $r15
+
+ // incoming fifo command?
+ iord $r10 I[$r0 + 0x200] // INTR
+ and $r11 $r10 0x00000004
+ bra e #ih_no_fifo
+ // queue incoming fifo command for later processing
+ mov $r11 0x1900
+ mov $r13 #cmd_queue
+ iord $r14 I[$r11 + 0x100] // FIFO_CMD
+ iord $r15 I[$r11 + 0x000] // FIFO_DATA
+ call #queue_put
+ add b32 $r11 0x400
+ mov $r14 1
+ iowr I[$r11 + 0x000] $r14 // FIFO_ACK
+
+ // context switch request?
+ ih_no_fifo:
+ and $r11 $r10 0x00000100
+ bra e #ih_no_ctxsw
+ // enqueue a context switch for later processing
+ mov $r13 #cmd_queue
+ mov $r14 0x4001
+ call #queue_put
+
+ // anything we didn't handle, bring it to the host's attention
+ ih_no_ctxsw:
+ mov $r11 0x104
+ not b32 $r11
+ and $r11 $r10 $r11
+ bra e #ih_no_other
+ mov $r10 0xc1c
+ shl b32 $r10 6
+ iowr I[$r10] $r11 // INTR_UP_SET
+
+ // ack, and wake up main()
+ ih_no_other:
+ iowr I[$r0 + 0x100] $r10 // INTR_ACK
+
+ pop $r15
+ pop $r14
+ pop $r13
+ pop $r11
+ pop $r10
+ pop $r9
+ pop $r8
+ mov $flags $r8
+ pop $r8
+ bclr $flags $p0
+ iret
+
+#ifdef NVGF
+// Not real sure, but, MEM_CMD 7 will hang forever if this isn't done
+ctx_4160s:
+ mov $r14 0x4160
+ sethi $r14 0x400000
+ mov $r15 1
+ call #nv_wr32
+ ctx_4160s_wait:
+ call #nv_rd32
+ xbit $r15 $r15 4
+ bra e #ctx_4160s_wait
+ ret
+
+// Without clearing again at end of xfer, some things cause PGRAPH
+// to hang with STATUS=0x00000007 until it's cleared.. fbcon can
+// still function with it set however...
+ctx_4160c:
+ mov $r14 0x4160
+ sethi $r14 0x400000
+ clear b32 $r15
+ call #nv_wr32
+ ret
+#endif
+
+// Again, not real sure
+//
+// In: $r15 value to set 0x404170 to
+//
+ctx_4170s:
+ mov $r14 0x4170
+ sethi $r14 0x400000
+ or $r15 0x10
+ call #nv_wr32
+ ret
+
+// Waits for a ctx_4170s() call to complete
+//
+ctx_4170w:
+ mov $r14 0x4170
+ sethi $r14 0x400000
+ call #nv_rd32
+ and $r15 0x10
+ bra ne #ctx_4170w
+ ret
+
+// Disables various things, waits a bit, and re-enables them..
+//
+// Not sure how exactly this helps, perhaps "ENABLE" is not such a
+// good description for the bits we turn off? Anyways, without this,
+// funny things happen.
+//
+ctx_redswitch:
+ mov $r14 0x614
+ shl b32 $r14 6
+ mov $r15 0x270
+ iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
+ mov $r15 8
+ ctx_redswitch_delay:
+ sub b32 $r15 1
+ bra ne #ctx_redswitch_delay
+ mov $r15 0x770
+ iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
+ ret
+
+// Not a clue what this is for, except that unless the value is 0x10, the
+// strand context is saved (and presumably restored) incorrectly..
+//
+// In: $r15 value to set to (0x00/0x10 are used)
+//
+ctx_86c:
+ mov $r14 0x86c
+ shl b32 $r14 6
+ iowr I[$r14] $r15 // HUB(0x86c) = val
+ mov $r14 -0x75ec
+ sethi $r14 0x400000
+ call #nv_wr32 // ROP(0xa14) = val
+ mov $r14 -0x5794
+ sethi $r14 0x410000
+ call #nv_wr32 // GPC(0x86c) = val
+ ret
+
+// ctx_load - load's a channel's ctxctl data, and selects its vm
+//
+// In: $r2 channel address
+//
+ctx_load:
+ trace_set(T_CHAN)
+
+ // switch to channel, somewhat magic in parts..
+ mov $r10 12 // DONE_UNK12
+ call #wait_donez
+ mov $r1 0xa24
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r0 // 0x409a24
+ mov $r3 0xb00
+ shl b32 $r3 6
+ iowr I[$r3 + 0x100] $r2 // CHAN_NEXT
+ mov $r1 0xa0c
+ shl b32 $r1 6
+ mov $r4 7
+ iowr I[$r1 + 0x000] $r2 // MEM_CHAN
+ iowr I[$r1 + 0x100] $r4 // MEM_CMD
+ ctx_chan_wait_0:
+ iord $r4 I[$r1 + 0x100]
+ and $r4 0x1f
+ bra ne #ctx_chan_wait_0
+ iowr I[$r3 + 0x000] $r2 // CHAN_CUR
+
+ // load channel header, fetch PGRAPH context pointer
+ mov $xtargets $r0
+ bclr $r2 31
+ shl b32 $r2 4
+ add b32 $r2 2
+
+ trace_set(T_LCHAN)
+ mov $r1 0xa04
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r2 // MEM_BASE
+ mov $r1 0xa20
+ shl b32 $r1 6
+ mov $r2 0x0002
+ sethi $r2 0x80000000
+ iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram
+ mov $r1 0x10 // chan + 0x0210
+ mov $r2 #xfer_data
+ sethi $r2 0x00020000 // 16 bytes
+ xdld $r1 $r2
+ xdwait
+ trace_clr(T_LCHAN)
+
+ // update current context
+ ld b32 $r1 D[$r0 + #xfer_data + 4]
+ shl b32 $r1 24
+ ld b32 $r2 D[$r0 + #xfer_data + 0]
+ shr b32 $r2 8
+ or $r1 $r2
+ st b32 D[$r0 + #ctx_current] $r1
+
+ // set transfer base to start of context, and fetch context header
+ trace_set(T_LCTXH)
+ mov $r2 0xa04
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r1 // MEM_BASE
+ mov $r2 1
+ mov $r1 0xa20
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm
+ mov $r1 #chan_data
+ sethi $r1 0x00060000 // 256 bytes
+ xdld $r0 $r1
+ xdwait
+ trace_clr(T_LCTXH)
+
+ trace_clr(T_CHAN)
+ ret
+
+// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
+// the active channel for ctxctl, but not actually transfer
+// any context data. intended for use only during initial
+// context construction.
+//
+// In: $r2 channel address
+//
+ctx_chan:
+#ifdef NVGF
+ call #ctx_4160s
+#endif
+ call #ctx_load
+ mov $r10 12 // DONE_UNK12
+ call #wait_donez
+ mov $r1 0xa10
+ shl b32 $r1 6
+ mov $r2 5
+ iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???)
+ ctx_chan_wait:
+ iord $r2 I[$r1 + 0x000]
+ or $r2 $r2
+ bra ne #ctx_chan_wait
+#ifdef NVGF
+ call #ctx_4160c
+#endif
+ ret
+
+// Execute per-context state overrides list
+//
+// Only executed on the first load of a channel. Might want to look into
+// removing this and having the host directly modify the channel's context
+// to change this state... The nouveau DRM already builds this list as
+// it's definitely needed for NVIDIA's, so we may as well use it for now
+//
+// Input: $r1 mmio list length
+//
+ctx_mmio_exec:
+ // set transfer base to be the mmio list
+ ld b32 $r3 D[$r0 + #chan_mmio_address]
+ mov $r2 0xa04
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r3 // MEM_BASE
+
+ clear b32 $r3
+ ctx_mmio_loop:
+ // fetch next 256 bytes of mmio list if necessary
+ and $r4 $r3 0xff
+ bra ne #ctx_mmio_pull
+ mov $r5 #xfer_data
+ sethi $r5 0x00060000 // 256 bytes
+ xdld $r3 $r5
+ xdwait
+
+ // execute a single list entry
+ ctx_mmio_pull:
+ ld b32 $r14 D[$r4 + #xfer_data + 0x00]
+ ld b32 $r15 D[$r4 + #xfer_data + 0x04]
+ call #nv_wr32
+
+ // next!
+ add b32 $r3 8
+ sub b32 $r1 1
+ bra ne #ctx_mmio_loop
+
+ // set transfer base back to the current context
+ ctx_mmio_done:
+ ld b32 $r3 D[$r0 + #ctx_current]
+ iowr I[$r2 + 0x000] $r3 // MEM_BASE
+
+ // disable the mmio list now, we don't need/want to execute it again
+ st b32 D[$r0 + #chan_mmio_count] $r0
+ mov $r1 #chan_data
+ sethi $r1 0x00060000 // 256 bytes
+ xdst $r0 $r1
+ xdwait
+ ret
+
+// Transfer HUB context data between GPU and storage area
+//
+// In: $r2 channel address
+// $p1 clear on save, set on load
+// $p2 set if opposite direction done/will be done, so:
+// on save it means: "a load will follow this save"
+// on load it means: "a save preceeded this load"
+//
+ctx_xfer:
+ // according to mwk, some kind of wait for idle
+ mov $r15 0xc00
+ shl b32 $r15 6
+ mov $r14 4
+ iowr I[$r15 + 0x200] $r14
+ ctx_xfer_idle:
+ iord $r14 I[$r15 + 0x000]
+ and $r14 0x2000
+ bra ne #ctx_xfer_idle
+
+ bra not $p1 #ctx_xfer_pre
+ bra $p2 #ctx_xfer_pre_load
+ ctx_xfer_pre:
+ mov $r15 0x10
+ call #ctx_86c
+#ifdef NVGF
+ call #ctx_4160s
+#endif
+ bra not $p1 #ctx_xfer_exec
+
+ ctx_xfer_pre_load:
+ mov $r15 2
+ call #ctx_4170s
+ call #ctx_4170w
+ call #ctx_redswitch
+ clear b32 $r15
+ call #ctx_4170s
+ call #ctx_load
+
+ // fetch context pointer, and initiate xfer on all GPCs
+ ctx_xfer_exec:
+ ld b32 $r1 D[$r0 + #ctx_current]
+ mov $r2 0x414
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset
+ mov $r14 -0x5b00
+ sethi $r14 0x410000
+ mov b32 $r15 $r1
+ call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer
+ add b32 $r14 4
+ xbit $r15 $flags $p1
+ xbit $r2 $flags $p2
+ shl b32 $r2 1
+ or $r15 $r2
+ call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
+
+ // strands
+ mov $r1 0x4afc
+ sethi $r1 0x20000
+ mov $r2 0xc
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
+ call #strand_wait
+ mov $r2 0x47fc
+ sethi $r2 0x20000
+ iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
+ xbit $r2 $flags $p1
+ add b32 $r2 3
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
+
+ // mmio context
+ xbit $r10 $flags $p1 // direction
+ or $r10 6 // first, last
+ mov $r11 0 // base = 0
+ ld b32 $r12 D[$r0 + #hub_mmio_list_head]
+ ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
+ mov $r14 0 // not multi
+ call #mmctx_xfer
+
+ // wait for GPCs to all complete
+ mov $r10 8 // DONE_BAR
+ call #wait_doneo
+
+ // wait for strand xfer to complete
+ call #strand_wait
+
+ // post-op
+ bra $p1 #ctx_xfer_post
+ mov $r10 12 // DONE_UNK12
+ call #wait_donez
+ mov $r1 0xa10
+ shl b32 $r1 6
+ mov $r2 5
+ iowr I[$r1] $r2 // MEM_CMD
+ ctx_xfer_post_save_wait:
+ iord $r2 I[$r1]
+ or $r2 $r2
+ bra ne #ctx_xfer_post_save_wait
+
+ bra $p2 #ctx_xfer_done
+ ctx_xfer_post:
+ mov $r15 2
+ call #ctx_4170s
+ clear b32 $r15
+ call #ctx_86c
+ call #strand_post
+ call #ctx_4170w
+ clear b32 $r15
+ call #ctx_4170s
+
+ bra not $p1 #ctx_xfer_no_post_mmio
+ ld b32 $r1 D[$r0 + #chan_mmio_count]
+ or $r1 $r1
+ bra e #ctx_xfer_no_post_mmio
+ call #ctx_mmio_exec
+
+ ctx_xfer_no_post_mmio:
+#ifdef NVGF
+ call #ctx_4160c
+#endif
+
+ ctx_xfer_done:
+ ret
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
index 7fbdebb2bafb..f144f665b807 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
@@ -1,6 +1,5 @@
-/* fuc microcode for nvc0 PGRAPH/HUB
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,22 +19,16 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs <[email protected]>
*/
-/* To build:
- * m4 hubnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o hubnvc0.fuc.h
- */
+#define NVGF
+#include "macros.fuc"
.section #nvc0_grhub_data
-include(`nvc0.fuc')
-gpc_count: .b32 0
-rop_count: .b32 0
-cmd_queue: queue_init
-hub_mmio_list_head: .b32 0
-hub_mmio_list_tail: .b32 0
-
-ctx_current: .b32 0
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "hub.fuc"
chipsets:
.b8 0xc0 0 0 0
@@ -68,9 +61,12 @@ chipsets:
.b8 0 0 0 0
nvc0_hub_mmio_head:
+mmctx_data(0x40402c, 1)
+mmctx_data(0x404174, 1)
+nvd9_hub_mmio_head:
mmctx_data(0x17e91c, 2)
mmctx_data(0x400204, 2)
-mmctx_data(0x404004, 11)
+mmctx_data(0x404004, 10)
mmctx_data(0x404044, 1)
mmctx_data(0x404094, 14)
mmctx_data(0x4040d0, 7)
@@ -78,7 +74,7 @@ mmctx_data(0x4040f8, 1)
mmctx_data(0x404130, 3)
mmctx_data(0x404150, 3)
mmctx_data(0x404164, 2)
-mmctx_data(0x404174, 3)
+mmctx_data(0x404178, 2)
mmctx_data(0x404200, 8)
mmctx_data(0x404404, 14)
mmctx_data(0x404460, 4)
@@ -105,765 +101,19 @@ mmctx_data(0x4078bc, 1)
mmctx_data(0x408000, 7)
mmctx_data(0x408064, 1)
mmctx_data(0x408800, 3)
-mmctx_data(0x408900, 4)
+mmctx_data(0x408900, 3)
mmctx_data(0x408980, 1)
nvc0_hub_mmio_tail:
mmctx_data(0x4064c0, 2)
nvc1_hub_mmio_tail:
-
-nvd9_hub_mmio_head:
-mmctx_data(0x17e91c, 2)
-mmctx_data(0x400204, 2)
-mmctx_data(0x404004, 10)
-mmctx_data(0x404044, 1)
-mmctx_data(0x404094, 14)
-mmctx_data(0x4040d0, 7)
-mmctx_data(0x4040f8, 1)
-mmctx_data(0x404130, 3)
-mmctx_data(0x404150, 3)
-mmctx_data(0x404164, 2)
-mmctx_data(0x404178, 2)
-mmctx_data(0x404200, 8)
-mmctx_data(0x404404, 14)
-mmctx_data(0x404460, 4)
-mmctx_data(0x404480, 1)
-mmctx_data(0x404498, 1)
-mmctx_data(0x404604, 4)
-mmctx_data(0x404618, 32)
-mmctx_data(0x404698, 21)
-mmctx_data(0x4046f0, 2)
-mmctx_data(0x404700, 22)
-mmctx_data(0x405800, 1)
-mmctx_data(0x405830, 3)
-mmctx_data(0x405854, 1)
-mmctx_data(0x405870, 4)
-mmctx_data(0x405a00, 2)
-mmctx_data(0x405a18, 1)
-mmctx_data(0x406020, 1)
-mmctx_data(0x406028, 4)
-mmctx_data(0x4064a8, 2)
-mmctx_data(0x4064b4, 5)
-mmctx_data(0x407804, 1)
-mmctx_data(0x40780c, 6)
-mmctx_data(0x4078bc, 1)
-mmctx_data(0x408000, 7)
-mmctx_data(0x408064, 1)
-mmctx_data(0x408800, 3)
-mmctx_data(0x408900, 4)
-mmctx_data(0x408980, 1)
+mmctx_data(0x4064bc, 3)
nvd9_hub_mmio_tail:
-
-.align 256
-chan_data:
-chan_mmio_count: .b32 0
-chan_mmio_address: .b32 0
-
-.align 256
-xfer_data: .b32 0
+#undef INCLUDE_DATA
.section #nvc0_grhub_code
+#define INCLUDE_CODE
bra #init
-define(`include_code')
-include(`nvc0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nvc0.fuc)
-//
-error:
- push $r14
- mov $r14 0x814
- shl b32 $r14 6
- iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code
- mov $r14 0xc1c
- shl b32 $r14 6
- mov $r15 1
- iowr I[$r14 + 0x000] $r15 // INTR_UP_SET
- pop $r14
- ret
-
-// HUB fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-//
-// Output:
-// CC_SCRATCH[0]:
-// 31:31: set to signal completion
-// CC_SCRATCH[1]:
-// 31:0: total PGRAPH context size
-//
-init:
- clear b32 $r0
- mov $sp $r0
- mov $xdbase $r0
-
- // enable fifo access
- mov $r1 0x1200
- mov $r2 2
- iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
-
- // setup i0 handler, and route all interrupts to it
- mov $r1 #ih
- mov $iv0 $r1
- mov $r1 0x400
- iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
-
- // route HUB_CHANNEL_SWITCH to fuc interrupt 8
- mov $r3 0x404
- shl b32 $r3 6
- mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
- iowr I[$r3 + 0x000] $r2
-
- // not sure what these are, route them because NVIDIA does, and
- // the IRQ handler will signal the host if we ever get one.. we
- // may find out if/why we need to handle these if so..
- //
- mov $r2 0x2004
- iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
- mov $r2 0x200b
- iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
- mov $r2 0x200c
- iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
-
- // enable all INTR_UP interrupts
- mov $r2 0xc24
- shl b32 $r2 6
- not b32 $r3 $r0
- iowr I[$r2] $r3
-
- // enable fifo, ctxsw, 9, 10, 15 interrupts
- mov $r2 -0x78fc // 0x8704
- sethi $r2 0
- iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
-
- // fifo level triggered, rest edge
- sub b32 $r1 0x100
- mov $r2 4
- iowr I[$r1] $r2
-
- // enable interrupts
- bset $flags ie0
-
- // fetch enabled GPC/ROP counts
- mov $r14 -0x69fc // 0x409604
- sethi $r14 0x400000
- call #nv_rd32
- extr $r1 $r15 16:20
- st b32 D[$r0 + #rop_count] $r1
- and $r15 0x1f
- st b32 D[$r0 + #gpc_count] $r15
-
- // set BAR_REQMASK to GPC mask
- mov $r1 1
- shl b32 $r1 $r15
- sub b32 $r1 1
- mov $r2 0x40c
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r1
- iowr I[$r2 + 0x100] $r1
-
- // find context data for this chipset
- mov $r2 0x800
- shl b32 $r2 6
- iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
- mov $r15 #chipsets - 8
- init_find_chipset:
- add b32 $r15 8
- ld b32 $r3 D[$r15 + 0x00]
- cmpu b32 $r3 $r2
- bra e #init_context
- cmpu b32 $r3 0
- bra ne #init_find_chipset
- // unknown chipset
- ret
-
- // context size calculation, reserve first 256 bytes for use by fuc
- init_context:
- mov $r1 256
-
- // calculate size of mmio context data
- ld b16 $r14 D[$r15 + 4]
- ld b16 $r15 D[$r15 + 6]
- sethi $r14 0
- st b32 D[$r0 + #hub_mmio_list_head] $r14
- st b32 D[$r0 + #hub_mmio_list_tail] $r15
- call #mmctx_size
-
- // set mmctx base addresses now so we don't have to do it later,
- // they don't (currently) ever change
- mov $r3 0x700
- shl b32 $r3 6
- shr b32 $r4 $r1 8
- iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE
- iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE
- add b32 $r3 0x1300
- add b32 $r1 $r15
- shr b32 $r15 2
- iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!?
-
- // strands, base offset needs to be aligned to 256 bytes
- shr b32 $r1 8
- add b32 $r1 1
- shl b32 $r1 8
- mov b32 $r15 $r1
- call #strand_ctx_init
- add b32 $r1 $r15
-
- // initialise each GPC in sequence by passing in the offset of its
- // context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
- // has previously been uploaded by the host) running.
- //
- // the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
- // when it has completed, and return the size of its context data
- // in GPCn_CC_SCRATCH[1]
- //
- ld b32 $r3 D[$r0 + #gpc_count]
- mov $r4 0x2000
- sethi $r4 0x500000
- init_gpc:
- // setup, and start GPC ucode running
- add b32 $r14 $r4 0x804
- mov b32 $r15 $r1
- call #nv_wr32 // CC_SCRATCH[1] = ctx offset
- add b32 $r14 $r4 0x800
- mov b32 $r15 $r2
- call #nv_wr32 // CC_SCRATCH[0] = chipset
- add b32 $r14 $r4 0x10c
- clear b32 $r15
- call #nv_wr32
- add b32 $r14 $r4 0x104
- call #nv_wr32 // ENTRY
- add b32 $r14 $r4 0x100
- mov $r15 2 // CTRL_START_TRIGGER
- call #nv_wr32 // CTRL
-
- // wait for it to complete, and adjust context size
- add b32 $r14 $r4 0x800
- init_gpc_wait:
- call #nv_rd32
- xbit $r15 $r15 31
- bra e #init_gpc_wait
- add b32 $r14 $r4 0x804
- call #nv_rd32
- add b32 $r1 $r15
-
- // next!
- add b32 $r4 0x8000
- sub b32 $r3 1
- bra ne #init_gpc
-
- // save context size, and tell host we're ready
- mov $r2 0x800
- shl b32 $r2 6
- iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size
- add b32 $r2 0x800
- clear b32 $r1
- bset $r1 31
- iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
- // sleep until we have something to do
- bset $flags $p0
- sleep $p0
- mov $r13 #cmd_queue
- call #queue_get
- bra $p1 #main
-
- // context switch, requested by GPU?
- cmpu b32 $r14 0x4001
- bra ne #main_not_ctx_switch
- trace_set(T_AUTO)
- mov $r1 0xb00
- shl b32 $r1 6
- iord $r2 I[$r1 + 0x100] // CHAN_NEXT
- iord $r1 I[$r1 + 0x000] // CHAN_CUR
-
- xbit $r3 $r1 31
- bra e #chsw_no_prev
- xbit $r3 $r2 31
- bra e #chsw_prev_no_next
- push $r2
- mov b32 $r2 $r1
- trace_set(T_SAVE)
- bclr $flags $p1
- bset $flags $p2
- call #ctx_xfer
- trace_clr(T_SAVE);
- pop $r2
- trace_set(T_LOAD);
- bset $flags $p1
- call #ctx_xfer
- trace_clr(T_LOAD);
- bra #chsw_done
- chsw_prev_no_next:
- push $r2
- mov b32 $r2 $r1
- bclr $flags $p1
- bclr $flags $p2
- call #ctx_xfer
- pop $r2
- mov $r1 0xb00
- shl b32 $r1 6
- iowr I[$r1] $r2
- bra #chsw_done
- chsw_no_prev:
- xbit $r3 $r2 31
- bra e #chsw_done
- bset $flags $p1
- bclr $flags $p2
- call #ctx_xfer
-
- // ack the context switch request
- chsw_done:
- mov $r1 0xb0c
- shl b32 $r1 6
- mov $r2 1
- iowr I[$r1 + 0x000] $r2 // 0x409b0c
- trace_clr(T_AUTO)
- bra #main
-
- // request to set current channel? (*not* a context switch)
- main_not_ctx_switch:
- cmpu b32 $r14 0x0001
- bra ne #main_not_ctx_chan
- mov b32 $r2 $r15
- call #ctx_chan
- bra #main_done
-
- // request to store current channel context?
- main_not_ctx_chan:
- cmpu b32 $r14 0x0002
- bra ne #main_not_ctx_save
- trace_set(T_SAVE)
- bclr $flags $p1
- bclr $flags $p2
- call #ctx_xfer
- trace_clr(T_SAVE)
- bra #main_done
-
- main_not_ctx_save:
- shl b32 $r15 $r14 16
- or $r15 E_BAD_COMMAND
- call #error
- bra #main
-
- main_done:
- mov $r1 0x820
- shl b32 $r1 6
- clear b32 $r2
- bset $r2 31
- iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
- bra #main
-
-// interrupt handler
-ih:
- push $r8
- mov $r8 $flags
- push $r8
- push $r9
- push $r10
- push $r11
- push $r13
- push $r14
- push $r15
-
- // incoming fifo command?
- iord $r10 I[$r0 + 0x200] // INTR
- and $r11 $r10 0x00000004
- bra e #ih_no_fifo
- // queue incoming fifo command for later processing
- mov $r11 0x1900
- mov $r13 #cmd_queue
- iord $r14 I[$r11 + 0x100] // FIFO_CMD
- iord $r15 I[$r11 + 0x000] // FIFO_DATA
- call #queue_put
- add b32 $r11 0x400
- mov $r14 1
- iowr I[$r11 + 0x000] $r14 // FIFO_ACK
-
- // context switch request?
- ih_no_fifo:
- and $r11 $r10 0x00000100
- bra e #ih_no_ctxsw
- // enqueue a context switch for later processing
- mov $r13 #cmd_queue
- mov $r14 0x4001
- call #queue_put
-
- // anything we didn't handle, bring it to the host's attention
- ih_no_ctxsw:
- mov $r11 0x104
- not b32 $r11
- and $r11 $r10 $r11
- bra e #ih_no_other
- mov $r10 0xc1c
- shl b32 $r10 6
- iowr I[$r10] $r11 // INTR_UP_SET
-
- // ack, and wake up main()
- ih_no_other:
- iowr I[$r0 + 0x100] $r10 // INTR_ACK
-
- pop $r15
- pop $r14
- pop $r13
- pop $r11
- pop $r10
- pop $r9
- pop $r8
- mov $flags $r8
- pop $r8
- bclr $flags $p0
- iret
-
-// Not real sure, but, MEM_CMD 7 will hang forever if this isn't done
-ctx_4160s:
- mov $r14 0x4160
- sethi $r14 0x400000
- mov $r15 1
- call #nv_wr32
- ctx_4160s_wait:
- call #nv_rd32
- xbit $r15 $r15 4
- bra e #ctx_4160s_wait
- ret
-
-// Without clearing again at end of xfer, some things cause PGRAPH
-// to hang with STATUS=0x00000007 until it's cleared.. fbcon can
-// still function with it set however...
-ctx_4160c:
- mov $r14 0x4160
- sethi $r14 0x400000
- clear b32 $r15
- call #nv_wr32
- ret
-
-// Again, not real sure
-//
-// In: $r15 value to set 0x404170 to
-//
-ctx_4170s:
- mov $r14 0x4170
- sethi $r14 0x400000
- or $r15 0x10
- call #nv_wr32
- ret
-
-// Waits for a ctx_4170s() call to complete
-//
-ctx_4170w:
- mov $r14 0x4170
- sethi $r14 0x400000
- call #nv_rd32
- and $r15 0x10
- bra ne #ctx_4170w
- ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off? Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
- mov $r14 0x614
- shl b32 $r14 6
- mov $r15 0x270
- iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
- mov $r15 8
- ctx_redswitch_delay:
- sub b32 $r15 1
- bra ne #ctx_redswitch_delay
- mov $r15 0x770
- iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
- ret
-
-// Not a clue what this is for, except that unless the value is 0x10, the
-// strand context is saved (and presumably restored) incorrectly..
-//
-// In: $r15 value to set to (0x00/0x10 are used)
-//
-ctx_86c:
- mov $r14 0x86c
- shl b32 $r14 6
- iowr I[$r14] $r15 // HUB(0x86c) = val
- mov $r14 -0x75ec
- sethi $r14 0x400000
- call #nv_wr32 // ROP(0xa14) = val
- mov $r14 -0x5794
- sethi $r14 0x410000
- call #nv_wr32 // GPC(0x86c) = val
- ret
-
-// ctx_load - load's a channel's ctxctl data, and selects its vm
-//
-// In: $r2 channel address
-//
-ctx_load:
- trace_set(T_CHAN)
-
- // switch to channel, somewhat magic in parts..
- mov $r10 12 // DONE_UNK12
- call #wait_donez
- mov $r1 0xa24
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r0 // 0x409a24
- mov $r3 0xb00
- shl b32 $r3 6
- iowr I[$r3 + 0x100] $r2 // CHAN_NEXT
- mov $r1 0xa0c
- shl b32 $r1 6
- mov $r4 7
- iowr I[$r1 + 0x000] $r2 // MEM_CHAN
- iowr I[$r1 + 0x100] $r4 // MEM_CMD
- ctx_chan_wait_0:
- iord $r4 I[$r1 + 0x100]
- and $r4 0x1f
- bra ne #ctx_chan_wait_0
- iowr I[$r3 + 0x000] $r2 // CHAN_CUR
-
- // load channel header, fetch PGRAPH context pointer
- mov $xtargets $r0
- bclr $r2 31
- shl b32 $r2 4
- add b32 $r2 2
-
- trace_set(T_LCHAN)
- mov $r1 0xa04
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r2 // MEM_BASE
- mov $r1 0xa20
- shl b32 $r1 6
- mov $r2 0x0002
- sethi $r2 0x80000000
- iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram
- mov $r1 0x10 // chan + 0x0210
- mov $r2 #xfer_data
- sethi $r2 0x00020000 // 16 bytes
- xdld $r1 $r2
- xdwait
- trace_clr(T_LCHAN)
-
- // update current context
- ld b32 $r1 D[$r0 + #xfer_data + 4]
- shl b32 $r1 24
- ld b32 $r2 D[$r0 + #xfer_data + 0]
- shr b32 $r2 8
- or $r1 $r2
- st b32 D[$r0 + #ctx_current] $r1
-
- // set transfer base to start of context, and fetch context header
- trace_set(T_LCTXH)
- mov $r2 0xa04
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r1 // MEM_BASE
- mov $r2 1
- mov $r1 0xa20
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm
- mov $r1 #chan_data
- sethi $r1 0x00060000 // 256 bytes
- xdld $r0 $r1
- xdwait
- trace_clr(T_LCTXH)
-
- trace_clr(T_CHAN)
- ret
-
-// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
-// the active channel for ctxctl, but not actually transfer
-// any context data. intended for use only during initial
-// context construction.
-//
-// In: $r2 channel address
-//
-ctx_chan:
- call #ctx_4160s
- call #ctx_load
- mov $r10 12 // DONE_UNK12
- call #wait_donez
- mov $r1 0xa10
- shl b32 $r1 6
- mov $r2 5
- iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???)
- ctx_chan_wait:
- iord $r2 I[$r1 + 0x000]
- or $r2 $r2
- bra ne #ctx_chan_wait
- call #ctx_4160c
- ret
-
-// Execute per-context state overrides list
-//
-// Only executed on the first load of a channel. Might want to look into
-// removing this and having the host directly modify the channel's context
-// to change this state... The nouveau DRM already builds this list as
-// it's definitely needed for NVIDIA's, so we may as well use it for now
-//
-// Input: $r1 mmio list length
-//
-ctx_mmio_exec:
- // set transfer base to be the mmio list
- ld b32 $r3 D[$r0 + #chan_mmio_address]
- mov $r2 0xa04
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r3 // MEM_BASE
-
- clear b32 $r3
- ctx_mmio_loop:
- // fetch next 256 bytes of mmio list if necessary
- and $r4 $r3 0xff
- bra ne #ctx_mmio_pull
- mov $r5 #xfer_data
- sethi $r5 0x00060000 // 256 bytes
- xdld $r3 $r5
- xdwait
-
- // execute a single list entry
- ctx_mmio_pull:
- ld b32 $r14 D[$r4 + #xfer_data + 0x00]
- ld b32 $r15 D[$r4 + #xfer_data + 0x04]
- call #nv_wr32
-
- // next!
- add b32 $r3 8
- sub b32 $r1 1
- bra ne #ctx_mmio_loop
-
- // set transfer base back to the current context
- ctx_mmio_done:
- ld b32 $r3 D[$r0 + #ctx_current]
- iowr I[$r2 + 0x000] $r3 // MEM_BASE
-
- // disable the mmio list now, we don't need/want to execute it again
- st b32 D[$r0 + #chan_mmio_count] $r0
- mov $r1 #chan_data
- sethi $r1 0x00060000 // 256 bytes
- xdst $r0 $r1
- xdwait
- ret
-
-// Transfer HUB context data between GPU and storage area
-//
-// In: $r2 channel address
-// $p1 clear on save, set on load
-// $p2 set if opposite direction done/will be done, so:
-// on save it means: "a load will follow this save"
-// on load it means: "a save preceeded this load"
-//
-ctx_xfer:
- // according to mwk, some kind of wait for idle
- mov $r15 0xc00
- shl b32 $r15 6
- mov $r14 4
- iowr I[$r15 + 0x200] $r14
- ctx_xfer_idle:
- iord $r14 I[$r15 + 0x000]
- and $r14 0x2000
- bra ne #ctx_xfer_idle
-
- bra not $p1 #ctx_xfer_pre
- bra $p2 #ctx_xfer_pre_load
- ctx_xfer_pre:
- mov $r15 0x10
- call #ctx_86c
- call #ctx_4160s
- bra not $p1 #ctx_xfer_exec
-
- ctx_xfer_pre_load:
- mov $r15 2
- call #ctx_4170s
- call #ctx_4170w
- call #ctx_redswitch
- clear b32 $r15
- call #ctx_4170s
- call #ctx_load
-
- // fetch context pointer, and initiate xfer on all GPCs
- ctx_xfer_exec:
- ld b32 $r1 D[$r0 + #ctx_current]
- mov $r2 0x414
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset
- mov $r14 -0x5b00
- sethi $r14 0x410000
- mov b32 $r15 $r1
- call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer
- add b32 $r14 4
- xbit $r15 $flags $p1
- xbit $r2 $flags $p2
- shl b32 $r2 1
- or $r15 $r2
- call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
-
- // strands
- mov $r1 0x4afc
- sethi $r1 0x20000
- mov $r2 0xc
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
- call #strand_wait
- mov $r2 0x47fc
- sethi $r2 0x20000
- iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
- xbit $r2 $flags $p1
- add b32 $r2 3
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
- // mmio context
- xbit $r10 $flags $p1 // direction
- or $r10 6 // first, last
- mov $r11 0 // base = 0
- ld b32 $r12 D[$r0 + #hub_mmio_list_head]
- ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
- mov $r14 0 // not multi
- call #mmctx_xfer
-
- // wait for GPCs to all complete
- mov $r10 8 // DONE_BAR
- call #wait_doneo
-
- // wait for strand xfer to complete
- call #strand_wait
-
- // post-op
- bra $p1 #ctx_xfer_post
- mov $r10 12 // DONE_UNK12
- call #wait_donez
- mov $r1 0xa10
- shl b32 $r1 6
- mov $r2 5
- iowr I[$r1] $r2 // MEM_CMD
- ctx_xfer_post_save_wait:
- iord $r2 I[$r1]
- or $r2 $r2
- bra ne #ctx_xfer_post_save_wait
-
- bra $p2 #ctx_xfer_done
- ctx_xfer_post:
- mov $r15 2
- call #ctx_4170s
- clear b32 $r15
- call #ctx_86c
- call #strand_post
- call #ctx_4170w
- clear b32 $r15
- call #ctx_4170s
-
- bra not $p1 #ctx_xfer_no_post_mmio
- ld b32 $r1 D[$r0 + #chan_mmio_count]
- or $r1 $r1
- bra e #ctx_xfer_no_post_mmio
- call #ctx_mmio_exec
-
- ctx_xfer_no_post_mmio:
- call #ctx_4160c
-
- ctx_xfer_done:
- ret
-
+#include "com.fuc"
+#include "hub.fuc"
.align 256
+#undef INCLUDE_CODE
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
index bb03d2a1d57b..d1bf23001830 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
@@ -28,108 +28,7 @@ uint32_t nvc0_grhub_data[] = {
0x00000000,
/* 0x0058: ctx_current */
0x00000000,
-/* 0x005c: chipsets */
- 0x000000c0,
- 0x013c00a0,
- 0x000000c1,
- 0x014000a0,
- 0x000000c3,
- 0x013c00a0,
- 0x000000c4,
- 0x013c00a0,
- 0x000000c8,
- 0x013c00a0,
- 0x000000ce,
- 0x013c00a0,
- 0x000000cf,
- 0x013c00a0,
- 0x000000d9,
- 0x01dc0140,
0x00000000,
-/* 0x00a0: nvc0_hub_mmio_head */
- 0x0417e91c,
- 0x04400204,
- 0x28404004,
- 0x00404044,
- 0x34404094,
- 0x184040d0,
- 0x004040f8,
- 0x08404130,
- 0x08404150,
- 0x04404164,
- 0x08404174,
- 0x1c404200,
- 0x34404404,
- 0x0c404460,
- 0x00404480,
- 0x00404498,
- 0x0c404604,
- 0x7c404618,
- 0x50404698,
- 0x044046f0,
- 0x54404700,
- 0x00405800,
- 0x08405830,
- 0x00405854,
- 0x0c405870,
- 0x04405a00,
- 0x00405a18,
- 0x00406020,
- 0x0c406028,
- 0x044064a8,
- 0x044064b4,
- 0x00407804,
- 0x1440780c,
- 0x004078bc,
- 0x18408000,
- 0x00408064,
- 0x08408800,
- 0x0c408900,
- 0x00408980,
-/* 0x013c: nvc0_hub_mmio_tail */
- 0x044064c0,
-/* 0x0140: nvc1_hub_mmio_tail */
-/* 0x0140: nvd9_hub_mmio_head */
- 0x0417e91c,
- 0x04400204,
- 0x24404004,
- 0x00404044,
- 0x34404094,
- 0x184040d0,
- 0x004040f8,
- 0x08404130,
- 0x08404150,
- 0x04404164,
- 0x04404178,
- 0x1c404200,
- 0x34404404,
- 0x0c404460,
- 0x00404480,
- 0x00404498,
- 0x0c404604,
- 0x7c404618,
- 0x50404698,
- 0x044046f0,
- 0x54404700,
- 0x00405800,
- 0x08405830,
- 0x00405854,
- 0x0c405870,
- 0x04405a00,
- 0x00405a18,
- 0x00406020,
- 0x0c406028,
- 0x044064a8,
- 0x104064b4,
- 0x00407804,
- 0x1440780c,
- 0x004078bc,
- 0x18408000,
- 0x00408064,
- 0x08408800,
- 0x0c408900,
- 0x00408980,
-/* 0x01dc: nvd9_hub_mmio_tail */
0x00000000,
0x00000000,
0x00000000,
@@ -139,10 +38,7 @@ uint32_t nvc0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
-/* 0x0200: chan_data */
-/* 0x0200: chan_mmio_count */
0x00000000,
-/* 0x0204: chan_mmio_address */
0x00000000,
0x00000000,
0x00000000,
@@ -173,6 +69,75 @@ uint32_t nvc0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
+/* 0x0100: chan_data */
+/* 0x0100: chan_mmio_count */
+ 0x00000000,
+/* 0x0104: chan_mmio_address */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+/* 0x0200: xfer_data */
+ 0x00000000,
0x00000000,
0x00000000,
0x00000000,
@@ -206,8 +171,103 @@ uint32_t nvc0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
-/* 0x0300: xfer_data */
0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+/* 0x0300: chipsets */
+ 0x000000c0,
+ 0x03f0034c,
+ 0x000000c1,
+ 0x03f4034c,
+ 0x000000c3,
+ 0x03f0034c,
+ 0x000000c4,
+ 0x03f0034c,
+ 0x000000c8,
+ 0x03f0034c,
+ 0x000000ce,
+ 0x03f0034c,
+ 0x000000cf,
+ 0x03f0034c,
+ 0x000000d9,
+ 0x03f80354,
+ 0x000000d7,
+ 0x03f80354,
+ 0x00000000,
+/* 0x034c: nvc0_hub_mmio_head */
+ 0x0040402c,
+ 0x00404174,
+/* 0x0354: nvd9_hub_mmio_head */
+ 0x0417e91c,
+ 0x04400204,
+ 0x24404004,
+ 0x00404044,
+ 0x34404094,
+ 0x184040d0,
+ 0x004040f8,
+ 0x08404130,
+ 0x08404150,
+ 0x04404164,
+ 0x04404178,
+ 0x1c404200,
+ 0x34404404,
+ 0x0c404460,
+ 0x00404480,
+ 0x00404498,
+ 0x0c404604,
+ 0x7c404618,
+ 0x50404698,
+ 0x044046f0,
+ 0x54404700,
+ 0x00405800,
+ 0x08405830,
+ 0x00405854,
+ 0x0c405870,
+ 0x04405a00,
+ 0x00405a18,
+ 0x00406020,
+ 0x0c406028,
+ 0x044064a8,
+ 0x044064b4,
+ 0x00407804,
+ 0x1440780c,
+ 0x004078bc,
+ 0x18408000,
+ 0x00408064,
+ 0x08408800,
+ 0x08408900,
+ 0x00408980,
+/* 0x03f0: nvc0_hub_mmio_tail */
+ 0x044064c0,
+/* 0x03f4: nvc1_hub_mmio_tail */
+ 0x084064bc,
};
uint32_t nvc0_grhub_code[] = {
@@ -278,7 +338,7 @@ uint32_t nvc0_grhub_code[] = {
0x0089d000,
0x081887f1,
0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
+/* 0x00e2: wait_donez_ne */
0x87f1008a,
0x84b60400,
0x0088cf06,
@@ -295,7 +355,7 @@ uint32_t nvc0_grhub_code[] = {
0x87f10089,
0x84b60818,
0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x011c: wait_doneo_e */
0x040087f1,
0xcf0684b6,
0x8aff0088,
@@ -443,7 +503,7 @@ uint32_t nvc0_grhub_code[] = {
0x0017f100,
0x0227f012,
0xf10012d0,
- 0xfe05b917,
+ 0xfe05ba17,
0x17f10010,
0x10d00400,
0x0437f1c0,
@@ -477,403 +537,403 @@ uint32_t nvc0_grhub_code[] = {
0x4021d000,
0x080027f1,
0xcf0624b6,
- 0xf7f00022,
-/* 0x03a9: init_find_chipset */
- 0x08f0b654,
- 0xb800f398,
- 0x0bf40432,
- 0x0034b00b,
- 0xf8f11bf4,
-/* 0x03bd: init_context */
- 0x0017f100,
- 0x02fe5801,
- 0xf003ff58,
- 0x0e8000e3,
- 0x150f8014,
- 0x013d21f5,
- 0x070037f1,
- 0x950634b6,
- 0x34d00814,
- 0x4034d000,
- 0x130030b7,
- 0xb6001fbb,
- 0x3fd002f5,
- 0x0815b600,
- 0xb60110b6,
- 0x1fb90814,
- 0x6321f502,
- 0x001fbb02,
- 0xf1000398,
- 0xf0200047,
-/* 0x040e: init_gpc */
- 0x4ea05043,
- 0x1fb90804,
- 0x8d21f402,
- 0x08004ea0,
- 0xf4022fb9,
- 0x4ea08d21,
- 0xf4bd010c,
+ 0xf7f10022,
+/* 0x03aa: init_find_chipset */
+ 0xf0b602f8,
+ 0x00f39808,
+ 0xf40432b8,
+ 0x34b00b0b,
+ 0xf11bf400,
+/* 0x03be: init_context */
+ 0x17f100f8,
+ 0xfe580100,
+ 0x03ff5802,
+ 0x8000e3f0,
+ 0x0f80140e,
+ 0x3d21f515,
+ 0x0037f101,
+ 0x0634b607,
+ 0xd0081495,
+ 0x34d00034,
+ 0x0030b740,
+ 0x001fbb13,
+ 0xd002f5b6,
+ 0x15b6003f,
+ 0x0110b608,
+ 0xb90814b6,
+ 0x21f5021f,
+ 0x1fbb0263,
+ 0x00039800,
+ 0x200047f1,
+/* 0x040f: init_gpc */
+ 0xa05043f0,
+ 0xb908044e,
+ 0x21f4021f,
+ 0x004ea08d,
+ 0x022fb908,
0xa08d21f4,
- 0xf401044e,
- 0x4ea08d21,
- 0xf7f00100,
- 0x8d21f402,
- 0x08004ea0,
-/* 0x0440: init_gpc_wait */
- 0xc86821f4,
- 0x0bf41fff,
- 0x044ea0fa,
+ 0xbd010c4e,
+ 0x8d21f4f4,
+ 0x01044ea0,
+ 0xa08d21f4,
+ 0xf001004e,
+ 0x21f402f7,
+ 0x004ea08d,
+/* 0x0441: init_gpc_wait */
0x6821f408,
- 0xb7001fbb,
- 0xb6800040,
- 0x1bf40132,
- 0x0027f1b4,
- 0x0624b608,
- 0xb74021d0,
- 0xbd080020,
- 0x1f19f014,
-/* 0x0473: main */
- 0xf40021d0,
- 0x28f40031,
- 0x08d7f000,
- 0xf43921f4,
- 0xe4b1f401,
- 0x1bf54001,
- 0x87f100d1,
- 0x84b6083c,
- 0xf094bd06,
- 0x89d00499,
- 0x0017f100,
- 0x0614b60b,
- 0xcf4012cf,
- 0x13c80011,
- 0x7e0bf41f,
- 0xf41f23c8,
- 0x20f95a0b,
- 0xf10212b9,
+ 0xf41fffc8,
+ 0x4ea0fa0b,
+ 0x21f40804,
+ 0x001fbb68,
+ 0x800040b7,
+ 0xf40132b6,
+ 0x27f1b41b,
+ 0x24b60800,
+ 0x4021d006,
+ 0x080020b7,
+ 0x19f014bd,
+ 0x0021d01f,
+/* 0x0474: main */
+ 0xf40031f4,
+ 0xd7f00028,
+ 0x3921f408,
+ 0xb1f401f4,
+ 0xf54001e4,
+ 0xf100d11b,
0xb6083c87,
0x94bd0684,
- 0xd00799f0,
- 0x32f40089,
- 0x0231f401,
- 0x082921f5,
- 0x085c87f1,
+ 0xd00499f0,
+ 0x17f10089,
+ 0x14b60b00,
+ 0x4012cf06,
+ 0xc80011cf,
+ 0x0bf41f13,
+ 0x1f23c87e,
+ 0xf95a0bf4,
+ 0x0212b920,
+ 0x083c87f1,
0xbd0684b6,
0x0799f094,
- 0xfc0089d0,
- 0x3c87f120,
+ 0xf40089d0,
+ 0x31f40132,
+ 0x2a21f502,
+ 0x5c87f108,
0x0684b608,
0x99f094bd,
- 0x0089d006,
- 0xf50131f4,
- 0xf1082921,
- 0xb6085c87,
- 0x94bd0684,
- 0xd00699f0,
- 0x0ef40089,
-/* 0x0509: chsw_prev_no_next */
- 0xb920f931,
- 0x32f40212,
- 0x0232f401,
- 0x082921f5,
- 0x17f120fc,
- 0x14b60b00,
- 0x0012d006,
-/* 0x0527: chsw_no_prev */
- 0xc8130ef4,
- 0x0bf41f23,
- 0x0131f40d,
- 0xf50232f4,
-/* 0x0537: chsw_done */
- 0xf1082921,
- 0xb60b0c17,
- 0x27f00614,
- 0x0012d001,
+ 0x0089d007,
+ 0x87f120fc,
+ 0x84b6083c,
+ 0xf094bd06,
+ 0x89d00699,
+ 0x0131f400,
+ 0x082a21f5,
0x085c87f1,
0xbd0684b6,
- 0x0499f094,
- 0xf50089d0,
-/* 0x0557: main_not_ctx_switch */
- 0xb0ff200e,
- 0x1bf401e4,
- 0x02f2b90d,
- 0x07b521f5,
-/* 0x0567: main_not_ctx_chan */
- 0xb0420ef4,
- 0x1bf402e4,
- 0x3c87f12e,
+ 0x0699f094,
+ 0xf40089d0,
+/* 0x050a: chsw_prev_no_next */
+ 0x20f9310e,
+ 0xf40212b9,
+ 0x32f40132,
+ 0x2a21f502,
+ 0xf120fc08,
+ 0xb60b0017,
+ 0x12d00614,
+ 0x130ef400,
+/* 0x0528: chsw_no_prev */
+ 0xf41f23c8,
+ 0x31f40d0b,
+ 0x0232f401,
+ 0x082a21f5,
+/* 0x0538: chsw_done */
+ 0x0b0c17f1,
+ 0xf00614b6,
+ 0x12d00127,
+ 0x5c87f100,
0x0684b608,
0x99f094bd,
- 0x0089d007,
- 0xf40132f4,
- 0x21f50232,
- 0x87f10829,
- 0x84b6085c,
+ 0x0089d004,
+ 0xff200ef5,
+/* 0x0558: main_not_ctx_switch */
+ 0xf401e4b0,
+ 0xf2b90d1b,
+ 0xb621f502,
+ 0x420ef407,
+/* 0x0568: main_not_ctx_chan */
+ 0xf402e4b0,
+ 0x87f12e1b,
+ 0x84b6083c,
0xf094bd06,
0x89d00799,
- 0x110ef400,
-/* 0x0598: main_not_ctx_save */
- 0xf010ef94,
- 0x21f501f5,
- 0x0ef502ec,
-/* 0x05a6: main_done */
- 0x17f1fed1,
- 0x14b60820,
- 0xf024bd06,
- 0x12d01f29,
- 0xbe0ef500,
-/* 0x05b9: ih */
- 0xfe80f9fe,
- 0x80f90188,
- 0xa0f990f9,
- 0xd0f9b0f9,
- 0xf0f9e0f9,
- 0xc4800acf,
- 0x0bf404ab,
- 0x00b7f11d,
- 0x08d7f019,
- 0xcf40becf,
- 0x21f400bf,
- 0x00b0b704,
- 0x01e7f004,
-/* 0x05ef: ih_no_fifo */
- 0xe400bed0,
- 0xf40100ab,
- 0xd7f00d0b,
- 0x01e7f108,
- 0x0421f440,
-/* 0x0600: ih_no_ctxsw */
- 0x0104b7f1,
- 0xabffb0bd,
- 0x0d0bf4b4,
- 0x0c1ca7f1,
- 0xd006a4b6,
-/* 0x0616: ih_no_other */
- 0x0ad000ab,
- 0xfcf0fc40,
- 0xfcd0fce0,
- 0xfca0fcb0,
- 0xfe80fc90,
- 0x80fc0088,
- 0xf80032f4,
-/* 0x0631: ctx_4160s */
- 0x60e7f101,
- 0x40e3f041,
- 0xf401f7f0,
-/* 0x063e: ctx_4160s_wait */
- 0x21f48d21,
- 0x04ffc868,
- 0xf8fa0bf4,
-/* 0x0649: ctx_4160c */
- 0x60e7f100,
- 0x40e3f041,
- 0x21f4f4bd,
-/* 0x0657: ctx_4170s */
- 0xf100f88d,
- 0xf04170e7,
- 0xf5f040e3,
- 0x8d21f410,
-/* 0x0666: ctx_4170w */
+ 0x0132f400,
+ 0xf50232f4,
+ 0xf1082a21,
+ 0xb6085c87,
+ 0x94bd0684,
+ 0xd00799f0,
+ 0x0ef40089,
+/* 0x0599: main_not_ctx_save */
+ 0x10ef9411,
+ 0xf501f5f0,
+ 0xf502ec21,
+/* 0x05a7: main_done */
+ 0xf1fed10e,
+ 0xb6082017,
+ 0x24bd0614,
+ 0xd01f29f0,
+ 0x0ef50012,
+/* 0x05ba: ih */
+ 0x80f9febe,
+ 0xf90188fe,
+ 0xf990f980,
+ 0xf9b0f9a0,
+ 0xf9e0f9d0,
+ 0x800acff0,
+ 0xf404abc4,
+ 0xb7f11d0b,
+ 0xd7f01900,
+ 0x40becf08,
+ 0xf400bfcf,
+ 0xb0b70421,
+ 0xe7f00400,
+ 0x00bed001,
+/* 0x05f0: ih_no_fifo */
+ 0x0100abe4,
+ 0xf00d0bf4,
+ 0xe7f108d7,
+ 0x21f44001,
+/* 0x0601: ih_no_ctxsw */
+ 0x04b7f104,
+ 0xffb0bd01,
+ 0x0bf4b4ab,
+ 0x1ca7f10d,
+ 0x06a4b60c,
+/* 0x0617: ih_no_other */
+ 0xd000abd0,
+ 0xf0fc400a,
+ 0xd0fce0fc,
+ 0xa0fcb0fc,
+ 0x80fc90fc,
+ 0xfc0088fe,
+ 0x0032f480,
+/* 0x0632: ctx_4160s */
+ 0xe7f101f8,
+ 0xe3f04160,
+ 0x01f7f040,
+/* 0x063f: ctx_4160s_wait */
+ 0xf48d21f4,
+ 0xffc86821,
+ 0xfa0bf404,
+/* 0x064a: ctx_4160c */
0xe7f100f8,
- 0xe3f04170,
- 0x6821f440,
- 0xf410f4f0,
- 0x00f8f31b,
-/* 0x0678: ctx_redswitch */
- 0x0614e7f1,
- 0xf106e4b6,
- 0xd00270f7,
- 0xf7f000ef,
-/* 0x0689: ctx_redswitch_delay */
- 0x01f2b608,
- 0xf1fd1bf4,
- 0xd00770f7,
- 0x00f800ef,
-/* 0x0698: ctx_86c */
- 0x086ce7f1,
- 0xd006e4b6,
- 0xe7f100ef,
- 0xe3f08a14,
- 0x8d21f440,
- 0xa86ce7f1,
- 0xf441e3f0,
+ 0xe3f04160,
+ 0xf4f4bd40,
0x00f88d21,
-/* 0x06b8: ctx_load */
- 0x083c87f1,
- 0xbd0684b6,
- 0x0599f094,
- 0xf00089d0,
- 0x21f40ca7,
- 0x2417f1c9,
- 0x0614b60a,
- 0xf10010d0,
- 0xb60b0037,
- 0x32d00634,
- 0x0c17f140,
- 0x0614b60a,
- 0xd00747f0,
- 0x14d00012,
-/* 0x06f1: ctx_chan_wait_0 */
- 0x4014cf40,
- 0xf41f44f0,
- 0x32d0fa1b,
- 0x000bfe00,
- 0xb61f2af0,
- 0x20b60424,
- 0x3c87f102,
+/* 0x0658: ctx_4170s */
+ 0x4170e7f1,
+ 0xf040e3f0,
+ 0x21f410f5,
+/* 0x0667: ctx_4170w */
+ 0xf100f88d,
+ 0xf04170e7,
+ 0x21f440e3,
+ 0x10f4f068,
+ 0xf8f31bf4,
+/* 0x0679: ctx_redswitch */
+ 0x14e7f100,
+ 0x06e4b606,
+ 0x0270f7f1,
+ 0xf000efd0,
+/* 0x068a: ctx_redswitch_delay */
+ 0xf2b608f7,
+ 0xfd1bf401,
+ 0x0770f7f1,
+ 0xf800efd0,
+/* 0x0699: ctx_86c */
+ 0x6ce7f100,
+ 0x06e4b608,
+ 0xf100efd0,
+ 0xf08a14e7,
+ 0x21f440e3,
+ 0x6ce7f18d,
+ 0x41e3f0a8,
+ 0xf88d21f4,
+/* 0x06b9: ctx_load */
+ 0x3c87f100,
0x0684b608,
0x99f094bd,
- 0x0089d008,
- 0x0a0417f1,
+ 0x0089d005,
+ 0xf40ca7f0,
+ 0x17f1c921,
+ 0x14b60a24,
+ 0x0010d006,
+ 0x0b0037f1,
+ 0xd00634b6,
+ 0x17f14032,
+ 0x14b60a0c,
+ 0x0747f006,
+ 0xd00012d0,
+/* 0x06f2: ctx_chan_wait_0 */
+ 0x14cf4014,
+ 0x1f44f040,
+ 0xd0fa1bf4,
+ 0x0bfe0032,
+ 0x1f2af000,
+ 0xb60424b6,
+ 0x87f10220,
+ 0x84b6083c,
+ 0xf094bd06,
+ 0x89d00899,
+ 0x0417f100,
+ 0x0614b60a,
+ 0xf10012d0,
+ 0xb60a2017,
+ 0x27f00614,
+ 0x0023f102,
+ 0x0012d080,
+ 0xf11017f0,
+ 0xf0020027,
+ 0x12fa0223,
+ 0xf103f805,
+ 0xb6085c87,
+ 0x94bd0684,
+ 0xd00899f0,
+ 0x01980089,
+ 0x1814b681,
+ 0xb6800298,
+ 0x12fd0825,
+ 0x16018005,
+ 0x083c87f1,
+ 0xbd0684b6,
+ 0x0999f094,
+ 0xf10089d0,
+ 0xb60a0427,
+ 0x21d00624,
+ 0x0127f000,
+ 0x0a2017f1,
0xd00614b6,
0x17f10012,
- 0x14b60a20,
- 0x0227f006,
- 0x800023f1,
- 0xf00012d0,
- 0x27f11017,
- 0x23f00300,
- 0x0512fa02,
+ 0x13f00100,
+ 0x0501fa06,
0x87f103f8,
0x84b6085c,
0xf094bd06,
- 0x89d00899,
- 0xc1019800,
- 0x981814b6,
- 0x25b6c002,
- 0x0512fd08,
- 0xf1160180,
- 0xb6083c87,
- 0x94bd0684,
- 0xd00999f0,
- 0x27f10089,
- 0x24b60a04,
- 0x0021d006,
- 0xf10127f0,
- 0xb60a2017,
- 0x12d00614,
- 0x0017f100,
- 0x0613f002,
- 0xf80501fa,
- 0x5c87f103,
+ 0x89d00999,
+ 0x5c87f100,
0x0684b608,
0x99f094bd,
- 0x0089d009,
- 0x085c87f1,
- 0xbd0684b6,
- 0x0599f094,
- 0xf80089d0,
-/* 0x07b5: ctx_chan */
- 0x3121f500,
- 0xb821f506,
- 0x0ca7f006,
- 0xf1c921f4,
- 0xb60a1017,
- 0x27f00614,
- 0x0012d005,
-/* 0x07d0: ctx_chan_wait */
- 0xfd0012cf,
- 0x1bf40522,
- 0x4921f5fa,
-/* 0x07df: ctx_mmio_exec */
- 0x9800f806,
- 0x27f18103,
- 0x24b60a04,
- 0x0023d006,
-/* 0x07ee: ctx_mmio_loop */
- 0x34c434bd,
- 0x0f1bf4ff,
- 0x030057f1,
- 0xfa0653f0,
- 0x03f80535,
-/* 0x0800: ctx_mmio_pull */
- 0x98c04e98,
- 0x21f4c14f,
- 0x0830b68d,
- 0xf40112b6,
-/* 0x0812: ctx_mmio_done */
- 0x0398df1b,
- 0x0023d016,
- 0xf1800080,
- 0xf0020017,
- 0x01fa0613,
- 0xf803f806,
-/* 0x0829: ctx_xfer */
- 0x00f7f100,
- 0x06f4b60c,
- 0xd004e7f0,
-/* 0x0836: ctx_xfer_idle */
- 0xfecf80fe,
- 0x00e4f100,
- 0xf91bf420,
- 0xf40611f4,
-/* 0x0846: ctx_xfer_pre */
- 0xf7f01102,
- 0x9821f510,
- 0x3121f506,
- 0x1c11f406,
-/* 0x0854: ctx_xfer_pre_load */
- 0xf502f7f0,
- 0xf5065721,
- 0xf5066621,
- 0xbd067821,
- 0x5721f5f4,
- 0xb821f506,
-/* 0x086d: ctx_xfer_exec */
- 0x16019806,
- 0x041427f1,
- 0xd00624b6,
- 0xe7f10020,
- 0xe3f0a500,
- 0x021fb941,
- 0xb68d21f4,
- 0xfcf004e0,
- 0x022cf001,
- 0xfd0124b6,
- 0x21f405f2,
- 0xfc17f18d,
- 0x0213f04a,
- 0xd00c27f0,
- 0x21f50012,
- 0x27f10207,
- 0x23f047fc,
- 0x0020d002,
- 0xb6012cf0,
- 0x12d00320,
- 0x01acf000,
- 0xf006a5f0,
- 0x0c9800b7,
- 0x150d9814,
- 0xf500e7f0,
- 0xf0015c21,
- 0x21f508a7,
- 0x21f50103,
- 0x01f40207,
- 0x0ca7f022,
- 0xf1c921f4,
- 0xb60a1017,
- 0x27f00614,
- 0x0012d005,
-/* 0x08f4: ctx_xfer_post_save_wait */
- 0xfd0012cf,
- 0x1bf40522,
- 0x3202f4fa,
-/* 0x0900: ctx_xfer_post */
- 0xf502f7f0,
- 0xbd065721,
- 0x9821f5f4,
- 0x2621f506,
- 0x6621f502,
- 0xf5f4bd06,
- 0xf4065721,
- 0x01981011,
- 0x0511fd80,
- 0xf5070bf4,
-/* 0x092b: ctx_xfer_no_post_mmio */
- 0xf507df21,
-/* 0x092f: ctx_xfer_done */
- 0xf8064921,
- 0x00000000,
+ 0x0089d005,
+/* 0x07b6: ctx_chan */
+ 0x21f500f8,
+ 0x21f50632,
+ 0xa7f006b9,
+ 0xc921f40c,
+ 0x0a1017f1,
+ 0xf00614b6,
+ 0x12d00527,
+/* 0x07d1: ctx_chan_wait */
+ 0x0012cf00,
+ 0xf40522fd,
+ 0x21f5fa1b,
+ 0x00f8064a,
+/* 0x07e0: ctx_mmio_exec */
+ 0xf1410398,
+ 0xb60a0427,
+ 0x23d00624,
+/* 0x07ef: ctx_mmio_loop */
+ 0xc434bd00,
+ 0x1bf4ff34,
+ 0x0057f10f,
+ 0x0653f002,
+ 0xf80535fa,
+/* 0x0801: ctx_mmio_pull */
+ 0x804e9803,
+ 0xf4814f98,
+ 0x30b68d21,
+ 0x0112b608,
+/* 0x0813: ctx_mmio_done */
+ 0x98df1bf4,
+ 0x23d01603,
+ 0x40008000,
+ 0x010017f1,
+ 0xfa0613f0,
+ 0x03f80601,
+/* 0x082a: ctx_xfer */
+ 0xf7f100f8,
+ 0xf4b60c00,
+ 0x04e7f006,
+/* 0x0837: ctx_xfer_idle */
+ 0xcf80fed0,
+ 0xe4f100fe,
+ 0x1bf42000,
+ 0x0611f4f9,
+/* 0x0847: ctx_xfer_pre */
+ 0xf01102f4,
+ 0x21f510f7,
+ 0x21f50699,
+ 0x11f40632,
+/* 0x0855: ctx_xfer_pre_load */
+ 0x02f7f01c,
+ 0x065821f5,
+ 0x066721f5,
+ 0x067921f5,
+ 0x21f5f4bd,
+ 0x21f50658,
+/* 0x086e: ctx_xfer_exec */
+ 0x019806b9,
+ 0x1427f116,
+ 0x0624b604,
+ 0xf10020d0,
+ 0xf0a500e7,
+ 0x1fb941e3,
+ 0x8d21f402,
+ 0xf004e0b6,
+ 0x2cf001fc,
+ 0x0124b602,
+ 0xf405f2fd,
+ 0x17f18d21,
+ 0x13f04afc,
+ 0x0c27f002,
+ 0xf50012d0,
+ 0xf1020721,
+ 0xf047fc27,
+ 0x20d00223,
+ 0x012cf000,
+ 0xd00320b6,
+ 0xacf00012,
+ 0x06a5f001,
+ 0x9800b7f0,
+ 0x0d98140c,
+ 0x00e7f015,
+ 0x015c21f5,
+ 0xf508a7f0,
+ 0xf5010321,
+ 0xf4020721,
+ 0xa7f02201,
+ 0xc921f40c,
+ 0x0a1017f1,
+ 0xf00614b6,
+ 0x12d00527,
+/* 0x08f5: ctx_xfer_post_save_wait */
+ 0x0012cf00,
+ 0xf40522fd,
+ 0x02f4fa1b,
+/* 0x0901: ctx_xfer_post */
+ 0x02f7f032,
+ 0x065821f5,
+ 0x21f5f4bd,
+ 0x21f50699,
+ 0x21f50226,
+ 0xf4bd0667,
+ 0x065821f5,
+ 0x981011f4,
+ 0x11fd4001,
+ 0x070bf405,
+ 0x07e021f5,
+/* 0x092c: ctx_xfer_no_post_mmio */
+ 0x064a21f5,
+/* 0x0930: ctx_xfer_done */
+ 0x000000f8,
0x00000000,
0x00000000,
0x00000000,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
index 7fe9d7cf486b..c7225db6486c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
@@ -1,6 +1,5 @@
-/* fuc microcode for nve0 PGRAPH/HUB
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,22 +19,16 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs <[email protected]>
*/
-/* To build:
- * m4 nve0_grhub.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grhub.fuc.h
- */
+#define NVGK
+#include "macros.fuc"
.section #nve0_grhub_data
-include(`nve0.fuc')
-gpc_count: .b32 0
-rop_count: .b32 0
-cmd_queue: queue_init
-hub_mmio_list_head: .b32 0
-hub_mmio_list_tail: .b32 0
-
-ctx_current: .b32 0
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "hub.fuc"
chipsets:
.b8 0xe4 0 0 0
@@ -47,6 +40,9 @@ chipsets:
.b8 0xe6 0 0 0
.b16 #nve4_hub_mmio_head
.b16 #nve4_hub_mmio_tail
+.b8 0xf0 0 0 0
+.b16 #nvf0_hub_mmio_head
+.b16 #nvf0_hub_mmio_tail
.b8 0 0 0 0
nve4_hub_mmio_head:
@@ -103,691 +99,67 @@ mmctx_data(0x408900, 3)
mmctx_data(0x408980, 1)
nve4_hub_mmio_tail:
-.align 256
-chan_data:
-chan_mmio_count: .b32 0
-chan_mmio_address: .b32 0
-
-.align 256
-xfer_data: .b32 0
+nvf0_hub_mmio_head:
+mmctx_data(0x17e91c, 2)
+mmctx_data(0x400204, 2)
+mmctx_data(0x404004, 17)
+mmctx_data(0x4040a8, 9)
+mmctx_data(0x4040d0, 7)
+mmctx_data(0x4040f8, 1)
+mmctx_data(0x404100, 10)
+mmctx_data(0x404130, 3)
+mmctx_data(0x404150, 3)
+mmctx_data(0x404164, 1)
+mmctx_data(0x40417c, 2)
+mmctx_data(0x4041a0, 4)
+mmctx_data(0x404200, 4)
+mmctx_data(0x404404, 12)
+mmctx_data(0x404438, 1)
+mmctx_data(0x404460, 4)
+mmctx_data(0x404480, 1)
+mmctx_data(0x404498, 1)
+mmctx_data(0x404604, 4)
+mmctx_data(0x404618, 4)
+mmctx_data(0x40462c, 2)
+mmctx_data(0x404640, 1)
+mmctx_data(0x404654, 1)
+mmctx_data(0x404660, 1)
+mmctx_data(0x404678, 19)
+mmctx_data(0x4046c8, 3)
+mmctx_data(0x404700, 3)
+mmctx_data(0x404718, 10)
+mmctx_data(0x404744, 2)
+mmctx_data(0x404754, 1)
+mmctx_data(0x405800, 1)
+mmctx_data(0x405830, 3)
+mmctx_data(0x405854, 1)
+mmctx_data(0x405870, 4)
+mmctx_data(0x405a00, 2)
+mmctx_data(0x405a18, 1)
+mmctx_data(0x405b00, 1)
+mmctx_data(0x405b10, 1)
+mmctx_data(0x405b20, 1)
+mmctx_data(0x406020, 1)
+mmctx_data(0x406028, 4)
+mmctx_data(0x4064a8, 5)
+mmctx_data(0x4064c0, 12)
+mmctx_data(0x4064fc, 1)
+mmctx_data(0x407804, 1)
+mmctx_data(0x40780c, 6)
+mmctx_data(0x4078bc, 1)
+mmctx_data(0x408000, 7)
+mmctx_data(0x408064, 1)
+mmctx_data(0x408800, 3)
+mmctx_data(0x408840, 1)
+mmctx_data(0x408900, 3)
+mmctx_data(0x408980, 1)
+nvf0_hub_mmio_tail:
+#undef INCLUDE_DATA
.section #nve0_grhub_code
+#define INCLUDE_CODE
bra #init
-define(`include_code')
-include(`nve0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nve0.fuc)
-//
-error:
- push $r14
- mov $r14 0x814
- shl b32 $r14 6
- iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code
- mov $r14 0xc1c
- shl b32 $r14 6
- mov $r15 1
- iowr I[$r14 + 0x000] $r15 // INTR_UP_SET
- pop $r14
- ret
-
-// HUB fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-//
-// Output:
-// CC_SCRATCH[0]:
-// 31:31: set to signal completion
-// CC_SCRATCH[1]:
-// 31:0: total PGRAPH context size
-//
-init:
- clear b32 $r0
- mov $sp $r0
- mov $xdbase $r0
-
- // enable fifo access
- mov $r1 0x1200
- mov $r2 2
- iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
-
- // setup i0 handler, and route all interrupts to it
- mov $r1 #ih
- mov $iv0 $r1
- mov $r1 0x400
- iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
-
- // route HUB_CHANNEL_SWITCH to fuc interrupt 8
- mov $r3 0x404
- shl b32 $r3 6
- mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
- iowr I[$r3 + 0x000] $r2
-
- // not sure what these are, route them because NVIDIA does, and
- // the IRQ handler will signal the host if we ever get one.. we
- // may find out if/why we need to handle these if so..
- //
- mov $r2 0x2004
- iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
- mov $r2 0x200b
- iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
- mov $r2 0x200c
- iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
-
- // enable all INTR_UP interrupts
- mov $r2 0xc24
- shl b32 $r2 6
- not b32 $r3 $r0
- iowr I[$r2] $r3
-
- // enable fifo, ctxsw, 9, 10, 15 interrupts
- mov $r2 -0x78fc // 0x8704
- sethi $r2 0
- iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
-
- // fifo level triggered, rest edge
- sub b32 $r1 0x100
- mov $r2 4
- iowr I[$r1] $r2
-
- // enable interrupts
- bset $flags ie0
-
- // fetch enabled GPC/ROP counts
- mov $r14 -0x69fc // 0x409604
- sethi $r14 0x400000
- call #nv_rd32
- extr $r1 $r15 16:20
- st b32 D[$r0 + #rop_count] $r1
- and $r15 0x1f
- st b32 D[$r0 + #gpc_count] $r15
-
- // set BAR_REQMASK to GPC mask
- mov $r1 1
- shl b32 $r1 $r15
- sub b32 $r1 1
- mov $r2 0x40c
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r1
- iowr I[$r2 + 0x100] $r1
-
- // find context data for this chipset
- mov $r2 0x800
- shl b32 $r2 6
- iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
- mov $r15 #chipsets - 8
- init_find_chipset:
- add b32 $r15 8
- ld b32 $r3 D[$r15 + 0x00]
- cmpu b32 $r3 $r2
- bra e #init_context
- cmpu b32 $r3 0
- bra ne #init_find_chipset
- // unknown chipset
- ret
-
- // context size calculation, reserve first 256 bytes for use by fuc
- init_context:
- mov $r1 256
-
- // calculate size of mmio context data
- ld b16 $r14 D[$r15 + 4]
- ld b16 $r15 D[$r15 + 6]
- sethi $r14 0
- st b32 D[$r0 + #hub_mmio_list_head] $r14
- st b32 D[$r0 + #hub_mmio_list_tail] $r15
- call #mmctx_size
-
- // set mmctx base addresses now so we don't have to do it later,
- // they don't (currently) ever change
- mov $r3 0x700
- shl b32 $r3 6
- shr b32 $r4 $r1 8
- iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE
- iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE
- add b32 $r3 0x1300
- add b32 $r1 $r15
- shr b32 $r15 2
- iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!?
-
- // strands, base offset needs to be aligned to 256 bytes
- shr b32 $r1 8
- add b32 $r1 1
- shl b32 $r1 8
- mov b32 $r15 $r1
- call #strand_ctx_init
- add b32 $r1 $r15
-
- // initialise each GPC in sequence by passing in the offset of its
- // context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
- // has previously been uploaded by the host) running.
- //
- // the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
- // when it has completed, and return the size of its context data
- // in GPCn_CC_SCRATCH[1]
- //
- ld b32 $r3 D[$r0 + #gpc_count]
- mov $r4 0x2000
- sethi $r4 0x500000
- init_gpc:
- // setup, and start GPC ucode running
- add b32 $r14 $r4 0x804
- mov b32 $r15 $r1
- call #nv_wr32 // CC_SCRATCH[1] = ctx offset
- add b32 $r14 $r4 0x800
- mov b32 $r15 $r2
- call #nv_wr32 // CC_SCRATCH[0] = chipset
- add b32 $r14 $r4 0x10c
- clear b32 $r15
- call #nv_wr32
- add b32 $r14 $r4 0x104
- call #nv_wr32 // ENTRY
- add b32 $r14 $r4 0x100
- mov $r15 2 // CTRL_START_TRIGGER
- call #nv_wr32 // CTRL
-
- // wait for it to complete, and adjust context size
- add b32 $r14 $r4 0x800
- init_gpc_wait:
- call #nv_rd32
- xbit $r15 $r15 31
- bra e #init_gpc_wait
- add b32 $r14 $r4 0x804
- call #nv_rd32
- add b32 $r1 $r15
-
- // next!
- add b32 $r4 0x8000
- sub b32 $r3 1
- bra ne #init_gpc
-
- // save context size, and tell host we're ready
- mov $r2 0x800
- shl b32 $r2 6
- iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size
- add b32 $r2 0x800
- clear b32 $r1
- bset $r1 31
- iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
- // sleep until we have something to do
- bset $flags $p0
- sleep $p0
- mov $r13 #cmd_queue
- call #queue_get
- bra $p1 #main
-
- // context switch, requested by GPU?
- cmpu b32 $r14 0x4001
- bra ne #main_not_ctx_switch
- trace_set(T_AUTO)
- mov $r1 0xb00
- shl b32 $r1 6
- iord $r2 I[$r1 + 0x100] // CHAN_NEXT
- iord $r1 I[$r1 + 0x000] // CHAN_CUR
-
- xbit $r3 $r1 31
- bra e #chsw_no_prev
- xbit $r3 $r2 31
- bra e #chsw_prev_no_next
- push $r2
- mov b32 $r2 $r1
- trace_set(T_SAVE)
- bclr $flags $p1
- bset $flags $p2
- call #ctx_xfer
- trace_clr(T_SAVE);
- pop $r2
- trace_set(T_LOAD);
- bset $flags $p1
- call #ctx_xfer
- trace_clr(T_LOAD);
- bra #chsw_done
- chsw_prev_no_next:
- push $r2
- mov b32 $r2 $r1
- bclr $flags $p1
- bclr $flags $p2
- call #ctx_xfer
- pop $r2
- mov $r1 0xb00
- shl b32 $r1 6
- iowr I[$r1] $r2
- bra #chsw_done
- chsw_no_prev:
- xbit $r3 $r2 31
- bra e #chsw_done
- bset $flags $p1
- bclr $flags $p2
- call #ctx_xfer
-
- // ack the context switch request
- chsw_done:
- mov $r1 0xb0c
- shl b32 $r1 6
- mov $r2 1
- iowr I[$r1 + 0x000] $r2 // 0x409b0c
- trace_clr(T_AUTO)
- bra #main
-
- // request to set current channel? (*not* a context switch)
- main_not_ctx_switch:
- cmpu b32 $r14 0x0001
- bra ne #main_not_ctx_chan
- mov b32 $r2 $r15
- call #ctx_chan
- bra #main_done
-
- // request to store current channel context?
- main_not_ctx_chan:
- cmpu b32 $r14 0x0002
- bra ne #main_not_ctx_save
- trace_set(T_SAVE)
- bclr $flags $p1
- bclr $flags $p2
- call #ctx_xfer
- trace_clr(T_SAVE)
- bra #main_done
-
- main_not_ctx_save:
- shl b32 $r15 $r14 16
- or $r15 E_BAD_COMMAND
- call #error
- bra #main
-
- main_done:
- mov $r1 0x820
- shl b32 $r1 6
- clear b32 $r2
- bset $r2 31
- iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
- bra #main
-
-// interrupt handler
-ih:
- push $r8
- mov $r8 $flags
- push $r8
- push $r9
- push $r10
- push $r11
- push $r13
- push $r14
- push $r15
-
- // incoming fifo command?
- iord $r10 I[$r0 + 0x200] // INTR
- and $r11 $r10 0x00000004
- bra e #ih_no_fifo
- // queue incoming fifo command for later processing
- mov $r11 0x1900
- mov $r13 #cmd_queue
- iord $r14 I[$r11 + 0x100] // FIFO_CMD
- iord $r15 I[$r11 + 0x000] // FIFO_DATA
- call #queue_put
- add b32 $r11 0x400
- mov $r14 1
- iowr I[$r11 + 0x000] $r14 // FIFO_ACK
-
- // context switch request?
- ih_no_fifo:
- and $r11 $r10 0x00000100
- bra e #ih_no_ctxsw
- // enqueue a context switch for later processing
- mov $r13 #cmd_queue
- mov $r14 0x4001
- call #queue_put
-
- // anything we didn't handle, bring it to the host's attention
- ih_no_ctxsw:
- mov $r11 0x104
- not b32 $r11
- and $r11 $r10 $r11
- bra e #ih_no_other
- mov $r10 0xc1c
- shl b32 $r10 6
- iowr I[$r10] $r11 // INTR_UP_SET
-
- // ack, and wake up main()
- ih_no_other:
- iowr I[$r0 + 0x100] $r10 // INTR_ACK
-
- pop $r15
- pop $r14
- pop $r13
- pop $r11
- pop $r10
- pop $r9
- pop $r8
- mov $flags $r8
- pop $r8
- bclr $flags $p0
- iret
-
-// Again, not real sure
-//
-// In: $r15 value to set 0x404170 to
-//
-ctx_4170s:
- mov $r14 0x4170
- sethi $r14 0x400000
- or $r15 0x10
- call #nv_wr32
- ret
-
-// Waits for a ctx_4170s() call to complete
-//
-ctx_4170w:
- mov $r14 0x4170
- sethi $r14 0x400000
- call #nv_rd32
- and $r15 0x10
- bra ne #ctx_4170w
- ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off? Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
- mov $r14 0x614
- shl b32 $r14 6
- mov $r15 0x270
- iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
- mov $r15 8
- ctx_redswitch_delay:
- sub b32 $r15 1
- bra ne #ctx_redswitch_delay
- mov $r15 0x770
- iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
- ret
-
-// Not a clue what this is for, except that unless the value is 0x10, the
-// strand context is saved (and presumably restored) incorrectly..
-//
-// In: $r15 value to set to (0x00/0x10 are used)
-//
-ctx_86c:
- mov $r14 0x86c
- shl b32 $r14 6
- iowr I[$r14] $r15 // HUB(0x86c) = val
- mov $r14 -0x75ec
- sethi $r14 0x400000
- call #nv_wr32 // ROP(0xa14) = val
- mov $r14 -0x5794
- sethi $r14 0x410000
- call #nv_wr32 // GPC(0x86c) = val
- ret
-
-// ctx_load - load's a channel's ctxctl data, and selects its vm
-//
-// In: $r2 channel address
-//
-ctx_load:
- trace_set(T_CHAN)
-
- // switch to channel, somewhat magic in parts..
- mov $r10 12 // DONE_UNK12
- call #wait_donez
- mov $r1 0xa24
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r0 // 0x409a24
- mov $r3 0xb00
- shl b32 $r3 6
- iowr I[$r3 + 0x100] $r2 // CHAN_NEXT
- mov $r1 0xa0c
- shl b32 $r1 6
- mov $r4 7
- iowr I[$r1 + 0x000] $r2 // MEM_CHAN
- iowr I[$r1 + 0x100] $r4 // MEM_CMD
- ctx_chan_wait_0:
- iord $r4 I[$r1 + 0x100]
- and $r4 0x1f
- bra ne #ctx_chan_wait_0
- iowr I[$r3 + 0x000] $r2 // CHAN_CUR
-
- // load channel header, fetch PGRAPH context pointer
- mov $xtargets $r0
- bclr $r2 31
- shl b32 $r2 4
- add b32 $r2 2
-
- trace_set(T_LCHAN)
- mov $r1 0xa04
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r2 // MEM_BASE
- mov $r1 0xa20
- shl b32 $r1 6
- mov $r2 0x0002
- sethi $r2 0x80000000
- iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram
- mov $r1 0x10 // chan + 0x0210
- mov $r2 #xfer_data
- sethi $r2 0x00020000 // 16 bytes
- xdld $r1 $r2
- xdwait
- trace_clr(T_LCHAN)
-
- // update current context
- ld b32 $r1 D[$r0 + #xfer_data + 4]
- shl b32 $r1 24
- ld b32 $r2 D[$r0 + #xfer_data + 0]
- shr b32 $r2 8
- or $r1 $r2
- st b32 D[$r0 + #ctx_current] $r1
-
- // set transfer base to start of context, and fetch context header
- trace_set(T_LCTXH)
- mov $r2 0xa04
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r1 // MEM_BASE
- mov $r2 1
- mov $r1 0xa20
- shl b32 $r1 6
- iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm
- mov $r1 #chan_data
- sethi $r1 0x00060000 // 256 bytes
- xdld $r0 $r1
- xdwait
- trace_clr(T_LCTXH)
-
- trace_clr(T_CHAN)
- ret
-
-// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
-// the active channel for ctxctl, but not actually transfer
-// any context data. intended for use only during initial
-// context construction.
-//
-// In: $r2 channel address
-//
-ctx_chan:
- call #ctx_load
- mov $r10 12 // DONE_UNK12
- call #wait_donez
- mov $r1 0xa10
- shl b32 $r1 6
- mov $r2 5
- iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???)
- ctx_chan_wait:
- iord $r2 I[$r1 + 0x000]
- or $r2 $r2
- bra ne #ctx_chan_wait
- ret
-
-// Execute per-context state overrides list
-//
-// Only executed on the first load of a channel. Might want to look into
-// removing this and having the host directly modify the channel's context
-// to change this state... The nouveau DRM already builds this list as
-// it's definitely needed for NVIDIA's, so we may as well use it for now
-//
-// Input: $r1 mmio list length
-//
-ctx_mmio_exec:
- // set transfer base to be the mmio list
- ld b32 $r3 D[$r0 + #chan_mmio_address]
- mov $r2 0xa04
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r3 // MEM_BASE
-
- clear b32 $r3
- ctx_mmio_loop:
- // fetch next 256 bytes of mmio list if necessary
- and $r4 $r3 0xff
- bra ne #ctx_mmio_pull
- mov $r5 #xfer_data
- sethi $r5 0x00060000 // 256 bytes
- xdld $r3 $r5
- xdwait
-
- // execute a single list entry
- ctx_mmio_pull:
- ld b32 $r14 D[$r4 + #xfer_data + 0x00]
- ld b32 $r15 D[$r4 + #xfer_data + 0x04]
- call #nv_wr32
-
- // next!
- add b32 $r3 8
- sub b32 $r1 1
- bra ne #ctx_mmio_loop
-
- // set transfer base back to the current context
- ctx_mmio_done:
- ld b32 $r3 D[$r0 + #ctx_current]
- iowr I[$r2 + 0x000] $r3 // MEM_BASE
-
- // disable the mmio list now, we don't need/want to execute it again
- st b32 D[$r0 + #chan_mmio_count] $r0
- mov $r1 #chan_data
- sethi $r1 0x00060000 // 256 bytes
- xdst $r0 $r1
- xdwait
- ret
-
-// Transfer HUB context data between GPU and storage area
-//
-// In: $r2 channel address
-// $p1 clear on save, set on load
-// $p2 set if opposite direction done/will be done, so:
-// on save it means: "a load will follow this save"
-// on load it means: "a save preceeded this load"
-//
-ctx_xfer:
- // according to mwk, some kind of wait for idle
- mov $r15 0xc00
- shl b32 $r15 6
- mov $r14 4
- iowr I[$r15 + 0x200] $r14
- ctx_xfer_idle:
- iord $r14 I[$r15 + 0x000]
- and $r14 0x2000
- bra ne #ctx_xfer_idle
-
- bra not $p1 #ctx_xfer_pre
- bra $p2 #ctx_xfer_pre_load
- ctx_xfer_pre:
- mov $r15 0x10
- call #ctx_86c
- bra not $p1 #ctx_xfer_exec
-
- ctx_xfer_pre_load:
- mov $r15 2
- call #ctx_4170s
- call #ctx_4170w
- call #ctx_redswitch
- clear b32 $r15
- call #ctx_4170s
- call #ctx_load
-
- // fetch context pointer, and initiate xfer on all GPCs
- ctx_xfer_exec:
- ld b32 $r1 D[$r0 + #ctx_current]
- mov $r2 0x414
- shl b32 $r2 6
- iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset
- mov $r14 -0x5b00
- sethi $r14 0x410000
- mov b32 $r15 $r1
- call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer
- add b32 $r14 4
- xbit $r15 $flags $p1
- xbit $r2 $flags $p2
- shl b32 $r2 1
- or $r15 $r2
- call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
-
- // strands
- mov $r1 0x4afc
- sethi $r1 0x20000
- mov $r2 0xc
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
- call #strand_wait
- mov $r2 0x47fc
- sethi $r2 0x20000
- iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
- xbit $r2 $flags $p1
- add b32 $r2 3
- iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
- // mmio context
- xbit $r10 $flags $p1 // direction
- or $r10 6 // first, last
- mov $r11 0 // base = 0
- ld b32 $r12 D[$r0 + #hub_mmio_list_head]
- ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
- mov $r14 0 // not multi
- call #mmctx_xfer
-
- // wait for GPCs to all complete
- mov $r10 8 // DONE_BAR
- call #wait_doneo
-
- // wait for strand xfer to complete
- call #strand_wait
-
- // post-op
- bra $p1 #ctx_xfer_post
- mov $r10 12 // DONE_UNK12
- call #wait_donez
- mov $r1 0xa10
- shl b32 $r1 6
- mov $r2 5
- iowr I[$r1] $r2 // MEM_CMD
- ctx_xfer_post_save_wait:
- iord $r2 I[$r1]
- or $r2 $r2
- bra ne #ctx_xfer_post_save_wait
-
- bra $p2 #ctx_xfer_done
- ctx_xfer_post:
- mov $r15 2
- call #ctx_4170s
- clear b32 $r15
- call #ctx_86c
- call #strand_post
- call #ctx_4170w
- clear b32 $r15
- call #ctx_4170s
-
- bra not $p1 #ctx_xfer_no_post_mmio
- ld b32 $r1 D[$r0 + #chan_mmio_count]
- or $r1 $r1
- bra e #ctx_xfer_no_post_mmio
- call #ctx_mmio_exec
-
- ctx_xfer_no_post_mmio:
-
- ctx_xfer_done:
- ret
-
+#include "com.fuc"
+#include "hub.fuc"
.align 256
+#undef INCLUDE_CODE
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
index e3421af68ab9..623e8698ace1 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
@@ -28,67 +28,7 @@ uint32_t nve0_grhub_data[] = {
0x00000000,
/* 0x0058: ctx_current */
0x00000000,
-/* 0x005c: chipsets */
- 0x000000e4,
- 0x01440078,
- 0x000000e7,
- 0x01440078,
- 0x000000e6,
- 0x01440078,
0x00000000,
-/* 0x0078: nve4_hub_mmio_head */
- 0x0417e91c,
- 0x04400204,
- 0x18404010,
- 0x204040a8,
- 0x184040d0,
- 0x004040f8,
- 0x08404130,
- 0x08404150,
- 0x00404164,
- 0x0c4041a0,
- 0x0c404200,
- 0x34404404,
- 0x0c404460,
- 0x00404480,
- 0x00404498,
- 0x0c404604,
- 0x0c404618,
- 0x0440462c,
- 0x00404640,
- 0x00404654,
- 0x00404660,
- 0x48404678,
- 0x084046c8,
- 0x08404700,
- 0x24404718,
- 0x04404744,
- 0x00404754,
- 0x00405800,
- 0x08405830,
- 0x00405854,
- 0x0c405870,
- 0x04405a00,
- 0x00405a18,
- 0x00405b00,
- 0x00405b10,
- 0x00406020,
- 0x0c406028,
- 0x044064a8,
- 0x044064b4,
- 0x2c4064c0,
- 0x004064fc,
- 0x00407040,
- 0x00407804,
- 0x1440780c,
- 0x004078bc,
- 0x18408000,
- 0x00408064,
- 0x08408800,
- 0x00408840,
- 0x08408900,
- 0x00408980,
-/* 0x0144: nve4_hub_mmio_tail */
0x00000000,
0x00000000,
0x00000000,
@@ -129,6 +69,26 @@ uint32_t nve0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
+/* 0x0100: chan_data */
+/* 0x0100: chan_mmio_count */
+ 0x00000000,
+/* 0x0104: chan_mmio_address */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
0x00000000,
0x00000000,
0x00000000,
@@ -136,10 +96,7 @@ uint32_t nve0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
-/* 0x0200: chan_data */
-/* 0x0200: chan_mmio_count */
0x00000000,
-/* 0x0204: chan_mmio_address */
0x00000000,
0x00000000,
0x00000000,
@@ -179,6 +136,7 @@ uint32_t nve0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
+/* 0x0200: xfer_data */
0x00000000,
0x00000000,
0x00000000,
@@ -203,8 +161,163 @@ uint32_t nve0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
-/* 0x0300: xfer_data */
0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+/* 0x0300: chipsets */
+ 0x000000e4,
+ 0x03f00324,
+ 0x000000e7,
+ 0x03f00324,
+ 0x000000e6,
+ 0x03f00324,
+ 0x000000f0,
+ 0x04c403f0,
+ 0x00000000,
+/* 0x0324: nve4_hub_mmio_head */
+ 0x0417e91c,
+ 0x04400204,
+ 0x18404010,
+ 0x204040a8,
+ 0x184040d0,
+ 0x004040f8,
+ 0x08404130,
+ 0x08404150,
+ 0x00404164,
+ 0x0c4041a0,
+ 0x0c404200,
+ 0x34404404,
+ 0x0c404460,
+ 0x00404480,
+ 0x00404498,
+ 0x0c404604,
+ 0x0c404618,
+ 0x0440462c,
+ 0x00404640,
+ 0x00404654,
+ 0x00404660,
+ 0x48404678,
+ 0x084046c8,
+ 0x08404700,
+ 0x24404718,
+ 0x04404744,
+ 0x00404754,
+ 0x00405800,
+ 0x08405830,
+ 0x00405854,
+ 0x0c405870,
+ 0x04405a00,
+ 0x00405a18,
+ 0x00405b00,
+ 0x00405b10,
+ 0x00406020,
+ 0x0c406028,
+ 0x044064a8,
+ 0x044064b4,
+ 0x2c4064c0,
+ 0x004064fc,
+ 0x00407040,
+ 0x00407804,
+ 0x1440780c,
+ 0x004078bc,
+ 0x18408000,
+ 0x00408064,
+ 0x08408800,
+ 0x00408840,
+ 0x08408900,
+ 0x00408980,
+/* 0x03f0: nve4_hub_mmio_tail */
+/* 0x03f0: nvf0_hub_mmio_head */
+ 0x0417e91c,
+ 0x04400204,
+ 0x40404004,
+ 0x204040a8,
+ 0x184040d0,
+ 0x004040f8,
+ 0x24404100,
+ 0x08404130,
+ 0x08404150,
+ 0x00404164,
+ 0x0440417c,
+ 0x0c4041a0,
+ 0x0c404200,
+ 0x2c404404,
+ 0x00404438,
+ 0x0c404460,
+ 0x00404480,
+ 0x00404498,
+ 0x0c404604,
+ 0x0c404618,
+ 0x0440462c,
+ 0x00404640,
+ 0x00404654,
+ 0x00404660,
+ 0x48404678,
+ 0x084046c8,
+ 0x08404700,
+ 0x24404718,
+ 0x04404744,
+ 0x00404754,
+ 0x00405800,
+ 0x08405830,
+ 0x00405854,
+ 0x0c405870,
+ 0x04405a00,
+ 0x00405a18,
+ 0x00405b00,
+ 0x00405b10,
+ 0x00405b20,
+ 0x00406020,
+ 0x0c406028,
+ 0x104064a8,
+ 0x2c4064c0,
+ 0x004064fc,
+ 0x00407804,
+ 0x1440780c,
+ 0x004078bc,
+ 0x18408000,
+ 0x00408064,
+ 0x08408800,
+ 0x00408840,
+ 0x08408900,
+ 0x00408980,
};
uint32_t nve0_grhub_code[] = {
@@ -275,7 +388,7 @@ uint32_t nve0_grhub_code[] = {
0x0089d000,
0x081887f1,
0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
+/* 0x00e2: wait_donez_ne */
0x87f1008a,
0x84b60400,
0x0088cf06,
@@ -292,7 +405,7 @@ uint32_t nve0_grhub_code[] = {
0x87f10089,
0x84b60818,
0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x011c: wait_doneo_e */
0x040087f1,
0xcf0684b6,
0x8aff0088,
@@ -440,7 +553,7 @@ uint32_t nve0_grhub_code[] = {
0x0017f100,
0x0227f012,
0xf10012d0,
- 0xfe05b917,
+ 0xfe05ba17,
0x17f10010,
0x10d00400,
0x0437f1c0,
@@ -474,385 +587,385 @@ uint32_t nve0_grhub_code[] = {
0x4021d000,
0x080027f1,
0xcf0624b6,
- 0xf7f00022,
-/* 0x03a9: init_find_chipset */
- 0x08f0b654,
- 0xb800f398,
- 0x0bf40432,
- 0x0034b00b,
- 0xf8f11bf4,
-/* 0x03bd: init_context */
- 0x0017f100,
- 0x02fe5801,
- 0xf003ff58,
- 0x0e8000e3,
- 0x150f8014,
- 0x013d21f5,
- 0x070037f1,
- 0x950634b6,
- 0x34d00814,
- 0x4034d000,
- 0x130030b7,
- 0xb6001fbb,
- 0x3fd002f5,
- 0x0815b600,
- 0xb60110b6,
- 0x1fb90814,
- 0x6321f502,
- 0x001fbb02,
- 0xf1000398,
- 0xf0200047,
-/* 0x040e: init_gpc */
- 0x4ea05043,
- 0x1fb90804,
- 0x8d21f402,
- 0x08004ea0,
- 0xf4022fb9,
- 0x4ea08d21,
- 0xf4bd010c,
+ 0xf7f10022,
+/* 0x03aa: init_find_chipset */
+ 0xf0b602f8,
+ 0x00f39808,
+ 0xf40432b8,
+ 0x34b00b0b,
+ 0xf11bf400,
+/* 0x03be: init_context */
+ 0x17f100f8,
+ 0xfe580100,
+ 0x03ff5802,
+ 0x8000e3f0,
+ 0x0f80140e,
+ 0x3d21f515,
+ 0x0037f101,
+ 0x0634b607,
+ 0xd0081495,
+ 0x34d00034,
+ 0x0030b740,
+ 0x001fbb13,
+ 0xd002f5b6,
+ 0x15b6003f,
+ 0x0110b608,
+ 0xb90814b6,
+ 0x21f5021f,
+ 0x1fbb0263,
+ 0x00039800,
+ 0x200047f1,
+/* 0x040f: init_gpc */
+ 0xa05043f0,
+ 0xb908044e,
+ 0x21f4021f,
+ 0x004ea08d,
+ 0x022fb908,
0xa08d21f4,
- 0xf401044e,
- 0x4ea08d21,
- 0xf7f00100,
- 0x8d21f402,
- 0x08004ea0,
-/* 0x0440: init_gpc_wait */
- 0xc86821f4,
- 0x0bf41fff,
- 0x044ea0fa,
+ 0xbd010c4e,
+ 0x8d21f4f4,
+ 0x01044ea0,
+ 0xa08d21f4,
+ 0xf001004e,
+ 0x21f402f7,
+ 0x004ea08d,
+/* 0x0441: init_gpc_wait */
0x6821f408,
- 0xb7001fbb,
- 0xb6800040,
- 0x1bf40132,
- 0x0027f1b4,
- 0x0624b608,
- 0xb74021d0,
- 0xbd080020,
- 0x1f19f014,
-/* 0x0473: main */
- 0xf40021d0,
- 0x28f40031,
- 0x08d7f000,
- 0xf43921f4,
- 0xe4b1f401,
- 0x1bf54001,
- 0x87f100d1,
- 0x84b6083c,
- 0xf094bd06,
- 0x89d00499,
- 0x0017f100,
- 0x0614b60b,
- 0xcf4012cf,
- 0x13c80011,
- 0x7e0bf41f,
- 0xf41f23c8,
- 0x20f95a0b,
- 0xf10212b9,
+ 0xf41fffc8,
+ 0x4ea0fa0b,
+ 0x21f40804,
+ 0x001fbb68,
+ 0x800040b7,
+ 0xf40132b6,
+ 0x27f1b41b,
+ 0x24b60800,
+ 0x4021d006,
+ 0x080020b7,
+ 0x19f014bd,
+ 0x0021d01f,
+/* 0x0474: main */
+ 0xf40031f4,
+ 0xd7f00028,
+ 0x3921f408,
+ 0xb1f401f4,
+ 0xf54001e4,
+ 0xf100d11b,
0xb6083c87,
0x94bd0684,
- 0xd00799f0,
- 0x32f40089,
- 0x0231f401,
- 0x07fb21f5,
- 0x085c87f1,
+ 0xd00499f0,
+ 0x17f10089,
+ 0x14b60b00,
+ 0x4012cf06,
+ 0xc80011cf,
+ 0x0bf41f13,
+ 0x1f23c87e,
+ 0xf95a0bf4,
+ 0x0212b920,
+ 0x083c87f1,
0xbd0684b6,
0x0799f094,
- 0xfc0089d0,
- 0x3c87f120,
+ 0xf40089d0,
+ 0x31f40132,
+ 0xfc21f502,
+ 0x5c87f107,
0x0684b608,
0x99f094bd,
- 0x0089d006,
- 0xf50131f4,
- 0xf107fb21,
- 0xb6085c87,
- 0x94bd0684,
- 0xd00699f0,
- 0x0ef40089,
-/* 0x0509: chsw_prev_no_next */
- 0xb920f931,
- 0x32f40212,
- 0x0232f401,
- 0x07fb21f5,
- 0x17f120fc,
- 0x14b60b00,
- 0x0012d006,
-/* 0x0527: chsw_no_prev */
- 0xc8130ef4,
- 0x0bf41f23,
- 0x0131f40d,
- 0xf50232f4,
-/* 0x0537: chsw_done */
- 0xf107fb21,
- 0xb60b0c17,
- 0x27f00614,
- 0x0012d001,
+ 0x0089d007,
+ 0x87f120fc,
+ 0x84b6083c,
+ 0xf094bd06,
+ 0x89d00699,
+ 0x0131f400,
+ 0x07fc21f5,
0x085c87f1,
0xbd0684b6,
- 0x0499f094,
- 0xf50089d0,
-/* 0x0557: main_not_ctx_switch */
- 0xb0ff200e,
- 0x1bf401e4,
- 0x02f2b90d,
- 0x078f21f5,
-/* 0x0567: main_not_ctx_chan */
- 0xb0420ef4,
- 0x1bf402e4,
- 0x3c87f12e,
+ 0x0699f094,
+ 0xf40089d0,
+/* 0x050a: chsw_prev_no_next */
+ 0x20f9310e,
+ 0xf40212b9,
+ 0x32f40132,
+ 0xfc21f502,
+ 0xf120fc07,
+ 0xb60b0017,
+ 0x12d00614,
+ 0x130ef400,
+/* 0x0528: chsw_no_prev */
+ 0xf41f23c8,
+ 0x31f40d0b,
+ 0x0232f401,
+ 0x07fc21f5,
+/* 0x0538: chsw_done */
+ 0x0b0c17f1,
+ 0xf00614b6,
+ 0x12d00127,
+ 0x5c87f100,
0x0684b608,
0x99f094bd,
- 0x0089d007,
- 0xf40132f4,
- 0x21f50232,
- 0x87f107fb,
- 0x84b6085c,
+ 0x0089d004,
+ 0xff200ef5,
+/* 0x0558: main_not_ctx_switch */
+ 0xf401e4b0,
+ 0xf2b90d1b,
+ 0x9021f502,
+ 0x420ef407,
+/* 0x0568: main_not_ctx_chan */
+ 0xf402e4b0,
+ 0x87f12e1b,
+ 0x84b6083c,
0xf094bd06,
0x89d00799,
- 0x110ef400,
-/* 0x0598: main_not_ctx_save */
- 0xf010ef94,
- 0x21f501f5,
- 0x0ef502ec,
-/* 0x05a6: main_done */
- 0x17f1fed1,
- 0x14b60820,
- 0xf024bd06,
- 0x12d01f29,
- 0xbe0ef500,
-/* 0x05b9: ih */
- 0xfe80f9fe,
- 0x80f90188,
- 0xa0f990f9,
- 0xd0f9b0f9,
- 0xf0f9e0f9,
- 0xc4800acf,
- 0x0bf404ab,
- 0x00b7f11d,
- 0x08d7f019,
- 0xcf40becf,
- 0x21f400bf,
- 0x00b0b704,
- 0x01e7f004,
-/* 0x05ef: ih_no_fifo */
- 0xe400bed0,
- 0xf40100ab,
- 0xd7f00d0b,
- 0x01e7f108,
- 0x0421f440,
-/* 0x0600: ih_no_ctxsw */
- 0x0104b7f1,
- 0xabffb0bd,
- 0x0d0bf4b4,
- 0x0c1ca7f1,
- 0xd006a4b6,
-/* 0x0616: ih_no_other */
- 0x0ad000ab,
- 0xfcf0fc40,
- 0xfcd0fce0,
- 0xfca0fcb0,
- 0xfe80fc90,
- 0x80fc0088,
- 0xf80032f4,
-/* 0x0631: ctx_4170s */
- 0x70e7f101,
+ 0x0132f400,
+ 0xf50232f4,
+ 0xf107fc21,
+ 0xb6085c87,
+ 0x94bd0684,
+ 0xd00799f0,
+ 0x0ef40089,
+/* 0x0599: main_not_ctx_save */
+ 0x10ef9411,
+ 0xf501f5f0,
+ 0xf502ec21,
+/* 0x05a7: main_done */
+ 0xf1fed10e,
+ 0xb6082017,
+ 0x24bd0614,
+ 0xd01f29f0,
+ 0x0ef50012,
+/* 0x05ba: ih */
+ 0x80f9febe,
+ 0xf90188fe,
+ 0xf990f980,
+ 0xf9b0f9a0,
+ 0xf9e0f9d0,
+ 0x800acff0,
+ 0xf404abc4,
+ 0xb7f11d0b,
+ 0xd7f01900,
+ 0x40becf08,
+ 0xf400bfcf,
+ 0xb0b70421,
+ 0xe7f00400,
+ 0x00bed001,
+/* 0x05f0: ih_no_fifo */
+ 0x0100abe4,
+ 0xf00d0bf4,
+ 0xe7f108d7,
+ 0x21f44001,
+/* 0x0601: ih_no_ctxsw */
+ 0x04b7f104,
+ 0xffb0bd01,
+ 0x0bf4b4ab,
+ 0x1ca7f10d,
+ 0x06a4b60c,
+/* 0x0617: ih_no_other */
+ 0xd000abd0,
+ 0xf0fc400a,
+ 0xd0fce0fc,
+ 0xa0fcb0fc,
+ 0x80fc90fc,
+ 0xfc0088fe,
+ 0x0032f480,
+/* 0x0632: ctx_4170s */
+ 0xe7f101f8,
+ 0xe3f04170,
+ 0x10f5f040,
+ 0xf88d21f4,
+/* 0x0641: ctx_4170w */
+ 0x70e7f100,
0x40e3f041,
- 0xf410f5f0,
- 0x00f88d21,
-/* 0x0640: ctx_4170w */
- 0x4170e7f1,
- 0xf440e3f0,
- 0xf4f06821,
- 0xf31bf410,
-/* 0x0652: ctx_redswitch */
- 0xe7f100f8,
- 0xe4b60614,
- 0x70f7f106,
- 0x00efd002,
-/* 0x0663: ctx_redswitch_delay */
- 0xb608f7f0,
- 0x1bf401f2,
- 0x70f7f1fd,
- 0x00efd007,
-/* 0x0672: ctx_86c */
- 0xe7f100f8,
- 0xe4b6086c,
- 0x00efd006,
- 0x8a14e7f1,
- 0xf440e3f0,
- 0xe7f18d21,
- 0xe3f0a86c,
- 0x8d21f441,
-/* 0x0692: ctx_load */
- 0x87f100f8,
- 0x84b6083c,
- 0xf094bd06,
- 0x89d00599,
- 0x0ca7f000,
- 0xf1c921f4,
- 0xb60a2417,
- 0x10d00614,
- 0x0037f100,
- 0x0634b60b,
- 0xf14032d0,
- 0xb60a0c17,
- 0x47f00614,
- 0x0012d007,
-/* 0x06cb: ctx_chan_wait_0 */
- 0xcf4014d0,
- 0x44f04014,
- 0xfa1bf41f,
- 0xfe0032d0,
- 0x2af0000b,
- 0x0424b61f,
- 0xf10220b6,
+ 0xf06821f4,
+ 0x1bf410f4,
+/* 0x0653: ctx_redswitch */
+ 0xf100f8f3,
+ 0xb60614e7,
+ 0xf7f106e4,
+ 0xefd00270,
+ 0x08f7f000,
+/* 0x0664: ctx_redswitch_delay */
+ 0xf401f2b6,
+ 0xf7f1fd1b,
+ 0xefd00770,
+/* 0x0673: ctx_86c */
+ 0xf100f800,
+ 0xb6086ce7,
+ 0xefd006e4,
+ 0x14e7f100,
+ 0x40e3f08a,
+ 0xf18d21f4,
+ 0xf0a86ce7,
+ 0x21f441e3,
+/* 0x0693: ctx_load */
+ 0xf100f88d,
0xb6083c87,
0x94bd0684,
- 0xd00899f0,
- 0x17f10089,
- 0x14b60a04,
- 0x0012d006,
- 0x0a2017f1,
+ 0xd00599f0,
+ 0xa7f00089,
+ 0xc921f40c,
+ 0x0a2417f1,
+ 0xd00614b6,
+ 0x37f10010,
+ 0x34b60b00,
+ 0x4032d006,
+ 0x0a0c17f1,
0xf00614b6,
- 0x23f10227,
- 0x12d08000,
- 0x1017f000,
- 0x030027f1,
- 0xfa0223f0,
- 0x03f80512,
- 0x085c87f1,
+ 0x12d00747,
+ 0x4014d000,
+/* 0x06cc: ctx_chan_wait_0 */
+ 0xf04014cf,
+ 0x1bf41f44,
+ 0x0032d0fa,
+ 0xf0000bfe,
+ 0x24b61f2a,
+ 0x0220b604,
+ 0x083c87f1,
0xbd0684b6,
0x0899f094,
- 0x980089d0,
- 0x14b6c101,
- 0xc0029818,
- 0xfd0825b6,
- 0x01800512,
- 0x3c87f116,
+ 0xf10089d0,
+ 0xb60a0417,
+ 0x12d00614,
+ 0x2017f100,
+ 0x0614b60a,
+ 0xf10227f0,
+ 0xd0800023,
+ 0x17f00012,
+ 0x0027f110,
+ 0x0223f002,
+ 0xf80512fa,
+ 0x5c87f103,
0x0684b608,
0x99f094bd,
- 0x0089d009,
- 0x0a0427f1,
- 0xd00624b6,
- 0x27f00021,
- 0x2017f101,
- 0x0614b60a,
- 0xf10012d0,
- 0xf0020017,
- 0x01fa0613,
- 0xf103f805,
+ 0x0089d008,
+ 0xb6810198,
+ 0x02981814,
+ 0x0825b680,
+ 0x800512fd,
+ 0x87f11601,
+ 0x84b6083c,
+ 0xf094bd06,
+ 0x89d00999,
+ 0x0427f100,
+ 0x0624b60a,
+ 0xf00021d0,
+ 0x17f10127,
+ 0x14b60a20,
+ 0x0012d006,
+ 0x010017f1,
+ 0xfa0613f0,
+ 0x03f80501,
+ 0x085c87f1,
+ 0xbd0684b6,
+ 0x0999f094,
+ 0xf10089d0,
0xb6085c87,
0x94bd0684,
- 0xd00999f0,
- 0x87f10089,
- 0x84b6085c,
- 0xf094bd06,
- 0x89d00599,
-/* 0x078f: ctx_chan */
- 0xf500f800,
- 0xf0069221,
- 0x21f40ca7,
- 0x1017f1c9,
- 0x0614b60a,
- 0xd00527f0,
-/* 0x07a6: ctx_chan_wait */
- 0x12cf0012,
- 0x0522fd00,
- 0xf8fa1bf4,
-/* 0x07b1: ctx_mmio_exec */
- 0x81039800,
- 0x0a0427f1,
- 0xd00624b6,
- 0x34bd0023,
-/* 0x07c0: ctx_mmio_loop */
- 0xf4ff34c4,
- 0x57f10f1b,
- 0x53f00300,
- 0x0535fa06,
-/* 0x07d2: ctx_mmio_pull */
- 0x4e9803f8,
- 0xc14f98c0,
- 0xb68d21f4,
- 0x12b60830,
- 0xdf1bf401,
-/* 0x07e4: ctx_mmio_done */
- 0xd0160398,
- 0x00800023,
- 0x0017f180,
- 0x0613f002,
- 0xf80601fa,
-/* 0x07fb: ctx_xfer */
- 0xf100f803,
- 0xb60c00f7,
- 0xe7f006f4,
- 0x80fed004,
-/* 0x0808: ctx_xfer_idle */
- 0xf100fecf,
- 0xf42000e4,
- 0x11f4f91b,
- 0x0d02f406,
-/* 0x0818: ctx_xfer_pre */
- 0xf510f7f0,
- 0xf4067221,
-/* 0x0822: ctx_xfer_pre_load */
- 0xf7f01c11,
- 0x3121f502,
- 0x4021f506,
- 0x5221f506,
- 0xf5f4bd06,
- 0xf5063121,
-/* 0x083b: ctx_xfer_exec */
- 0x98069221,
- 0x27f11601,
- 0x24b60414,
- 0x0020d006,
- 0xa500e7f1,
- 0xb941e3f0,
- 0x21f4021f,
- 0x04e0b68d,
- 0xf001fcf0,
- 0x24b6022c,
- 0x05f2fd01,
- 0xf18d21f4,
- 0xf04afc17,
- 0x27f00213,
- 0x0012d00c,
- 0x020721f5,
- 0x47fc27f1,
- 0xd00223f0,
- 0x2cf00020,
- 0x0320b601,
- 0xf00012d0,
- 0xa5f001ac,
- 0x00b7f006,
- 0x98140c98,
- 0xe7f0150d,
- 0x5c21f500,
- 0x08a7f001,
- 0x010321f5,
- 0x020721f5,
- 0xf02201f4,
- 0x21f40ca7,
- 0x1017f1c9,
- 0x0614b60a,
- 0xd00527f0,
-/* 0x08c2: ctx_xfer_post_save_wait */
- 0x12cf0012,
- 0x0522fd00,
- 0xf4fa1bf4,
-/* 0x08ce: ctx_xfer_post */
- 0xf7f02e02,
- 0x3121f502,
- 0xf5f4bd06,
- 0xf5067221,
- 0xf5022621,
- 0xbd064021,
- 0x3121f5f4,
- 0x1011f406,
- 0xfd800198,
- 0x0bf40511,
- 0xb121f507,
-/* 0x08f9: ctx_xfer_no_post_mmio */
-/* 0x08f9: ctx_xfer_done */
- 0x0000f807,
+ 0xd00599f0,
+ 0x00f80089,
+/* 0x0790: ctx_chan */
+ 0x069321f5,
+ 0xf40ca7f0,
+ 0x17f1c921,
+ 0x14b60a10,
+ 0x0527f006,
+/* 0x07a7: ctx_chan_wait */
+ 0xcf0012d0,
+ 0x22fd0012,
+ 0xfa1bf405,
+/* 0x07b2: ctx_mmio_exec */
+ 0x039800f8,
+ 0x0427f141,
+ 0x0624b60a,
+ 0xbd0023d0,
+/* 0x07c1: ctx_mmio_loop */
+ 0xff34c434,
+ 0xf10f1bf4,
+ 0xf0020057,
+ 0x35fa0653,
+/* 0x07d3: ctx_mmio_pull */
+ 0x9803f805,
+ 0x4f98804e,
+ 0x8d21f481,
+ 0xb60830b6,
+ 0x1bf40112,
+/* 0x07e5: ctx_mmio_done */
+ 0x160398df,
+ 0x800023d0,
+ 0x17f14000,
+ 0x13f00100,
+ 0x0601fa06,
+ 0x00f803f8,
+/* 0x07fc: ctx_xfer */
+ 0x0c00f7f1,
+ 0xf006f4b6,
+ 0xfed004e7,
+/* 0x0809: ctx_xfer_idle */
+ 0x00fecf80,
+ 0x2000e4f1,
+ 0xf4f91bf4,
+ 0x02f40611,
+/* 0x0819: ctx_xfer_pre */
+ 0x10f7f00d,
+ 0x067321f5,
+/* 0x0823: ctx_xfer_pre_load */
+ 0xf01c11f4,
+ 0x21f502f7,
+ 0x21f50632,
+ 0x21f50641,
+ 0xf4bd0653,
+ 0x063221f5,
+ 0x069321f5,
+/* 0x083c: ctx_xfer_exec */
+ 0xf1160198,
+ 0xb6041427,
+ 0x20d00624,
+ 0x00e7f100,
+ 0x41e3f0a5,
+ 0xf4021fb9,
+ 0xe0b68d21,
+ 0x01fcf004,
+ 0xb6022cf0,
+ 0xf2fd0124,
+ 0x8d21f405,
+ 0x4afc17f1,
+ 0xf00213f0,
+ 0x12d00c27,
+ 0x0721f500,
+ 0xfc27f102,
+ 0x0223f047,
+ 0xf00020d0,
+ 0x20b6012c,
+ 0x0012d003,
+ 0xf001acf0,
+ 0xb7f006a5,
+ 0x140c9800,
+ 0xf0150d98,
+ 0x21f500e7,
+ 0xa7f0015c,
+ 0x0321f508,
+ 0x0721f501,
+ 0x2201f402,
+ 0xf40ca7f0,
+ 0x17f1c921,
+ 0x14b60a10,
+ 0x0527f006,
+/* 0x08c3: ctx_xfer_post_save_wait */
+ 0xcf0012d0,
+ 0x22fd0012,
+ 0xfa1bf405,
+/* 0x08cf: ctx_xfer_post */
+ 0xf02e02f4,
+ 0x21f502f7,
+ 0xf4bd0632,
+ 0x067321f5,
+ 0x022621f5,
+ 0x064121f5,
+ 0x21f5f4bd,
+ 0x11f40632,
+ 0x40019810,
+ 0xf40511fd,
+ 0x21f5070b,
+/* 0x08fa: ctx_xfer_no_post_mmio */
+/* 0x08fa: ctx_xfer_done */
+ 0x00f807b2,
0x00000000,
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc
new file mode 100644
index 000000000000..43a0b9476efd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <[email protected]>
+ */
+
+#include "os.h"
+
+#define mmctx_data(r,c) .b32 (((c - 1) << 26) | r)
+#define queue_init .skip 72 // (2 * 4) + ((8 * 4) * 2)
+
+#define T_WAIT 0
+#define T_MMCTX 1
+#define T_STRWAIT 2
+#define T_STRINIT 3
+#define T_AUTO 4
+#define T_CHAN 5
+#define T_LOAD 6
+#define T_SAVE 7
+#define T_LCHAN 8
+#define T_LCTXH 9
+
+#define trace_set(bit) /*
+*/ mov $r8 0x83c /*
+*/ shl b32 $r8 6 /*
+*/ clear b32 $r9 /*
+*/ bset $r9 bit /*
+*/ iowr I[$r8 + 0x000] $r9
+
+#define trace_clr(bit) /*
+*/ mov $r8 0x85c /*
+*/ shl b32 $r8 6 /*
+*/ clear b32 $r9 /*
+*/ bset $r9 bit /*
+*/ iowr I[$r8 + 0x000] $r9
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc
deleted file mode 100644
index f16a5d53319d..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc
+++ /dev/null
@@ -1,400 +0,0 @@
-/* fuc microcode util functions for nve0 PGRAPH
- *
- * Copyright 2011 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
-define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
-
-ifdef(`include_code', `
-// Error codes
-define(`E_BAD_COMMAND', 0x01)
-define(`E_CMD_OVERFLOW', 0x02)
-
-// Util macros to help with debugging ucode hangs etc
-define(`T_WAIT', 0)
-define(`T_MMCTX', 1)
-define(`T_STRWAIT', 2)
-define(`T_STRINIT', 3)
-define(`T_AUTO', 4)
-define(`T_CHAN', 5)
-define(`T_LOAD', 6)
-define(`T_SAVE', 7)
-define(`T_LCHAN', 8)
-define(`T_LCTXH', 9)
-
-define(`trace_set', `
- mov $r8 0x83c
- shl b32 $r8 6
- clear b32 $r9
- bset $r9 $1
- iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
-')
-
-define(`trace_clr', `
- mov $r8 0x85c
- shl b32 $r8 6
- clear b32 $r9
- bset $r9 $1
- iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
-')
-
-// queue_put - add request to queue
-//
-// In : $r13 queue pointer
-// $r14 command
-// $r15 data
-//
-queue_put:
- // make sure we have space..
- ld b32 $r8 D[$r13 + 0x0] // GET
- ld b32 $r9 D[$r13 + 0x4] // PUT
- xor $r8 8
- cmpu b32 $r8 $r9
- bra ne #queue_put_next
- mov $r15 E_CMD_OVERFLOW
- call #error
- ret
-
- // store cmd/data on queue
- queue_put_next:
- and $r8 $r9 7
- shl b32 $r8 3
- add b32 $r8 $r13
- add b32 $r8 8
- st b32 D[$r8 + 0x0] $r14
- st b32 D[$r8 + 0x4] $r15
-
- // update PUT
- add b32 $r9 1
- and $r9 0xf
- st b32 D[$r13 + 0x4] $r9
- ret
-
-// queue_get - fetch request from queue
-//
-// In : $r13 queue pointer
-//
-// Out: $p1 clear on success (data available)
-// $r14 command
-// $r15 data
-//
-queue_get:
- bset $flags $p1
- ld b32 $r8 D[$r13 + 0x0] // GET
- ld b32 $r9 D[$r13 + 0x4] // PUT
- cmpu b32 $r8 $r9
- bra e #queue_get_done
- // fetch first cmd/data pair
- and $r9 $r8 7
- shl b32 $r9 3
- add b32 $r9 $r13
- add b32 $r9 8
- ld b32 $r14 D[$r9 + 0x0]
- ld b32 $r15 D[$r9 + 0x4]
-
- // update GET
- add b32 $r8 1
- and $r8 0xf
- st b32 D[$r13 + 0x0] $r8
- bclr $flags $p1
-queue_get_done:
- ret
-
-// nv_rd32 - read 32-bit value from nv register
-//
-// In : $r14 register
-// Out: $r15 value
-//
-nv_rd32:
- mov $r11 0x728
- shl b32 $r11 6
- mov b32 $r12 $r14
- bset $r12 31 // MMIO_CTRL_PENDING
- iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
- nv_rd32_wait:
- iord $r12 I[$r11 + 0x000]
- xbit $r12 $r12 31
- bra ne #nv_rd32_wait
- mov $r10 6 // DONE_MMIO_RD
- call #wait_doneo
- iord $r15 I[$r11 + 0x100] // MMIO_RDVAL
- ret
-
-// nv_wr32 - write 32-bit value to nv register
-//
-// In : $r14 register
-// $r15 value
-//
-nv_wr32:
- mov $r11 0x728
- shl b32 $r11 6
- iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL
- mov b32 $r12 $r14
- bset $r12 31 // MMIO_CTRL_PENDING
- bset $r12 30 // MMIO_CTRL_WRITE
- iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
- nv_wr32_wait:
- iord $r12 I[$r11 + 0x000]
- xbit $r12 $r12 31
- bra ne #nv_wr32_wait
- ret
-
-// (re)set watchdog timer
-//
-// In : $r15 timeout
-//
-watchdog_reset:
- mov $r8 0x430
- shl b32 $r8 6
- bset $r15 31
- iowr I[$r8 + 0x000] $r15
- ret
-
-// clear watchdog timer
-watchdog_clear:
- mov $r8 0x430
- shl b32 $r8 6
- iowr I[$r8 + 0x000] $r0
- ret
-
-// wait_done{z,o} - wait on FUC_DONE bit to become clear/set
-//
-// In : $r10 bit to wait on
-//
-define(`wait_done', `
-$1:
- trace_set(T_WAIT);
- mov $r8 0x818
- shl b32 $r8 6
- iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit
- wait_done_$1:
- mov $r8 0x400
- shl b32 $r8 6
- iord $r8 I[$r8 + 0x000] // DONE
- xbit $r8 $r8 $r10
- bra $2 #wait_done_$1
- trace_clr(T_WAIT)
- ret
-')
-wait_done(wait_donez, ne)
-wait_done(wait_doneo, e)
-
-// mmctx_size - determine size of a mmio list transfer
-//
-// In : $r14 mmio list head
-// $r15 mmio list tail
-// Out: $r15 transfer size (in bytes)
-//
-mmctx_size:
- clear b32 $r9
- nv_mmctx_size_loop:
- ld b32 $r8 D[$r14]
- shr b32 $r8 26
- add b32 $r8 1
- shl b32 $r8 2
- add b32 $r9 $r8
- add b32 $r14 4
- cmpu b32 $r14 $r15
- bra ne #nv_mmctx_size_loop
- mov b32 $r15 $r9
- ret
-
-// mmctx_xfer - execute a list of mmio transfers
-//
-// In : $r10 flags
-// bit 0: direction (0 = save, 1 = load)
-// bit 1: set if first transfer
-// bit 2: set if last transfer
-// $r11 base
-// $r12 mmio list head
-// $r13 mmio list tail
-// $r14 multi_stride
-// $r15 multi_mask
-//
-mmctx_xfer:
- trace_set(T_MMCTX)
- mov $r8 0x710
- shl b32 $r8 6
- clear b32 $r9
- or $r11 $r11
- bra e #mmctx_base_disabled
- iowr I[$r8 + 0x000] $r11 // MMCTX_BASE
- bset $r9 0 // BASE_EN
- mmctx_base_disabled:
- or $r14 $r14
- bra e #mmctx_multi_disabled
- iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE
- iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK
- bset $r9 1 // MULTI_EN
- mmctx_multi_disabled:
- add b32 $r8 0x100
-
- xbit $r11 $r10 0
- shl b32 $r11 16 // DIR
- bset $r11 12 // QLIMIT = 0x10
- xbit $r14 $r10 1
- shl b32 $r14 17
- or $r11 $r14 // START_TRIGGER
- iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
-
- // loop over the mmio list, and send requests to the hw
- mmctx_exec_loop:
- // wait for space in mmctx queue
- mmctx_wait_free:
- iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
- and $r14 0x1f
- bra e #mmctx_wait_free
-
- // queue up an entry
- ld b32 $r14 D[$r12]
- or $r14 $r9
- iowr I[$r8 + 0x300] $r14
- add b32 $r12 4
- cmpu b32 $r12 $r13
- bra ne #mmctx_exec_loop
-
- xbit $r11 $r10 2
- bra ne #mmctx_stop
- // wait for queue to empty
- mmctx_fini_wait:
- iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
- and $r11 0x1f
- cmpu b32 $r11 0x10
- bra ne #mmctx_fini_wait
- mov $r10 2 // DONE_MMCTX
- call #wait_donez
- bra #mmctx_done
- mmctx_stop:
- xbit $r11 $r10 0
- shl b32 $r11 16 // DIR
- bset $r11 12 // QLIMIT = 0x10
- bset $r11 18 // STOP_TRIGGER
- iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
- mmctx_stop_wait:
- // wait for STOP_TRIGGER to clear
- iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
- xbit $r11 $r11 18
- bra ne #mmctx_stop_wait
- mmctx_done:
- trace_clr(T_MMCTX)
- ret
-
-// Wait for DONE_STRAND
-//
-strand_wait:
- push $r10
- mov $r10 2
- call #wait_donez
- pop $r10
- ret
-
-// unknown - call before issuing strand commands
-//
-strand_pre:
- mov $r8 0x4afc
- sethi $r8 0x20000
- mov $r9 0xc
- iowr I[$r8] $r9
- call #strand_wait
- ret
-
-// unknown - call after issuing strand commands
-//
-strand_post:
- mov $r8 0x4afc
- sethi $r8 0x20000
- mov $r9 0xd
- iowr I[$r8] $r9
- call #strand_wait
- ret
-
-// Selects strand set?!
-//
-// In: $r14 id
-//
-strand_set:
- mov $r10 0x4ffc
- sethi $r10 0x20000
- sub b32 $r11 $r10 0x500
- mov $r12 0xf
- iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf
- mov $r12 0xb
- iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb
- call #strand_wait
- iowr I[$r10 + 0x000] $r14 // 0x93c = <id>
- mov $r12 0xa
- iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa
- call #strand_wait
- ret
-
-// Initialise strand context data
-//
-// In : $r15 context base
-// Out: $r15 context size (in bytes)
-//
-// Strandset(?) 3 hardcoded currently
-//
-strand_ctx_init:
- trace_set(T_STRINIT)
- call #strand_pre
- mov $r14 3
- call #strand_set
- mov $r10 0x46fc
- sethi $r10 0x20000
- add b32 $r11 $r10 0x400
- iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0
- mov $r12 1
- iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE
- call #strand_wait
- sub b32 $r12 $r0 1
- iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff
- mov $r12 2
- iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT
- call #strand_wait
- call #strand_post
-
- // read the size of each strand, poke the context offset of
- // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
- // about it later then.
- mov $r8 0x880
- shl b32 $r8 6
- iord $r9 I[$r8 + 0x000] // STRANDS
- add b32 $r8 0x2200
- shr b32 $r14 $r15 8
- ctx_init_strand_loop:
- iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE
- iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE
- iord $r10 I[$r8 + 0x200] // STRAND_SIZE
- shr b32 $r10 6
- add b32 $r10 1
- add b32 $r14 $r10
- add b32 $r8 4
- sub b32 $r9 1
- bra ne #ctx_init_strand_loop
-
- shl b32 $r14 8
- sub b32 $r15 $r14 $r15
- trace_clr(T_STRINIT)
- ret
-')
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h
new file mode 100644
index 000000000000..fd1d380de094
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_GRAPH_OS_H__
+#define __NVKM_GRAPH_OS_H__
+
+#define E_BAD_COMMAND 0x00000001
+#define E_CMD_OVERFLOW 0x00000002
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
index 1ac36110ca19..03de5175dd9f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
@@ -186,13 +186,6 @@ nv50_graph_cclass = {
* PGRAPH engine/subdev functions
******************************************************************************/
-static int
-nv50_graph_tlb_flush(struct nouveau_engine *engine)
-{
- nv50_vm_flush_engine(&engine->base, 0x00);
- return 0;
-}
-
static const struct nouveau_bitfield nv50_pgraph_status[] = {
{ 0x00000001, "BUSY" }, /* set when any bit is set */
{ 0x00000002, "DISPATCH" },
@@ -302,8 +295,10 @@ nv84_graph_tlb_flush(struct nouveau_engine *engine)
nv_rd32(priv, 0x400388));
}
- nv50_vm_flush_engine(&engine->base, 0x00);
+ nv_wr32(priv, 0x100c80, 0x00000001);
+ if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000))
+ nv_error(priv, "vm flush timeout\n");
nv_mask(priv, 0x400500, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&priv->lock, flags);
return timeout ? -EBUSY : 0;
@@ -857,10 +852,9 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
};
- if (nv_device(priv)->chipset == 0x50 ||
- nv_device(priv)->chipset == 0xac)
- nv_engine(priv)->tlb_flush = nv50_graph_tlb_flush;
- else
+ /* unfortunate hw bug workaround... */
+ if (nv_device(priv)->chipset != 0x50 &&
+ nv_device(priv)->chipset != 0xac)
nv_engine(priv)->tlb_flush = nv84_graph_tlb_flush;
spin_lock_init(&priv->lock);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
index f9b9d82c287f..d61c833be09f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -237,6 +237,43 @@ nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x409c20, ustat);
}
+static const struct nouveau_enum nvc0_mp_warp_error[] = {
+ { 0x00, "NO_ERROR" },
+ { 0x01, "STACK_MISMATCH" },
+ { 0x05, "MISALIGNED_PC" },
+ { 0x08, "MISALIGNED_GPR" },
+ { 0x09, "INVALID_OPCODE" },
+ { 0x0d, "GPR_OUT_OF_BOUNDS" },
+ { 0x0e, "MEM_OUT_OF_BOUNDS" },
+ { 0x0f, "UNALIGNED_MEM_ACCESS" },
+ { 0x11, "INVALID_PARAM" },
+ {}
+};
+
+static const struct nouveau_bitfield nvc0_mp_global_error[] = {
+ { 0x00000004, "MULTIPLE_WARP_ERRORS" },
+ { 0x00000008, "OUT_OF_STACK_SPACE" },
+ {}
+};
+
+static void
+nvc0_graph_trap_mp(struct nvc0_graph_priv *priv, int gpc, int tpc)
+{
+ u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x648));
+ u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x650));
+
+ nv_error(priv, "GPC%i/TPC%i/MP trap:", gpc, tpc);
+ nouveau_bitfield_print(nvc0_mp_global_error, gerr);
+ if (werr) {
+ pr_cont(" ");
+ nouveau_enum_print(nvc0_mp_warp_error, werr & 0xffff);
+ }
+ pr_cont("\n");
+
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x648), 0x00000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x650), gerr);
+}
+
static void
nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc)
{
@@ -251,12 +288,7 @@ nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc)
}
if (stat & 0x00000002) {
- u32 trap0 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0644));
- u32 trap1 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x064c));
- nv_error(priv, "GPC%d/TPC%d/MP: 0x%08x 0x%08x\n",
- gpc, tpc, trap0, trap1);
- nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0644), 0x001ffffe);
- nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x064c), 0x0000000f);
+ nvc0_graph_trap_mp(priv, gpc, tpc);
nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000002);
stat &= ~0x00000002;
}
@@ -685,6 +717,544 @@ nvc0_graph_init_regs(struct nvc0_graph_priv *priv)
}
static void
+nvc0_graph_init_unk40xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x40415c, 0x00000000);
+ nv_wr32(priv, 0x404170, 0x00000000);
+}
+
+static void
+nvc0_graph_init_unk44xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404488, 0x00000000);
+ nv_wr32(priv, 0x40448c, 0x00000000);
+}
+
+static void
+nvc0_graph_init_unk78xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x407808, 0x00000000);
+}
+
+static void
+nvc0_graph_init_unk60xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x406024, 0x00000000);
+}
+
+static void
+nvc0_graph_init_unk64xx(struct nvc0_graph_priv *priv)
+{
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x4064f0, 0x00000000);
+ nv_wr32(priv, 0x4064f4, 0x00000000);
+ nv_wr32(priv, 0x4064f8, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+}
+
+static void
+nvc0_graph_init_unk58xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x405844, 0x00ffffff);
+ nv_wr32(priv, 0x405850, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x405900, 0x00002834);
+ break;
+ case 0xc0:
+ case 0xc8:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x405908, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x405928, 0x00000000);
+ nv_wr32(priv, 0x40592c, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+}
+
+static void
+nvc0_graph_init_unk80xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x40803c, 0x00000000);
+}
+
+static void
+nvc0_graph_init_gpc(struct nvc0_graph_priv *priv)
+{
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418408, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x4184a0, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x4184a4, 0x00000000);
+ nv_wr32(priv, 0x4184a8, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x418604, 0x00000000);
+ nv_wr32(priv, 0x418680, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ case 0xc1:
+ nv_wr32(priv, 0x418714, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x418714, 0x80000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x418384, 0x00000000);
+ nv_wr32(priv, 0x418814, 0x00000000);
+ nv_wr32(priv, 0x418818, 0x00000000);
+ nv_wr32(priv, 0x41881c, 0x00000000);
+ nv_wr32(priv, 0x418b04, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ case 0xc1:
+ case 0xc8:
+ nv_wr32(priv, 0x4188c8, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x4188c8, 0x80000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x4188cc, 0x00000000);
+ nv_wr32(priv, 0x4188d0, 0x00010000);
+ nv_wr32(priv, 0x4188d4, 0x00000001);
+ nv_wr32(priv, 0x418910, 0x00010001);
+ nv_wr32(priv, 0x418914, 0x00000301);
+ nv_wr32(priv, 0x418918, 0x00800000);
+ nv_wr32(priv, 0x418980, 0x77777770);
+ nv_wr32(priv, 0x418984, 0x77777777);
+ nv_wr32(priv, 0x418988, 0x77777777);
+ nv_wr32(priv, 0x41898c, 0x77777777);
+ nv_wr32(priv, 0x418c04, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418c64, 0x00000000);
+ nv_wr32(priv, 0x418c68, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x418c88, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418cb4, 0x00000000);
+ nv_wr32(priv, 0x418cb8, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x418d00, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418d28, 0x00000000);
+ nv_wr32(priv, 0x418d2c, 0x00000000);
+ nv_wr32(priv, 0x418f00, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x418f08, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418f20, 0x00000000);
+ nv_wr32(priv, 0x418f24, 0x00000000);
+ /*fall-through*/
+ case 0xc1:
+ nv_wr32(priv, 0x418e00, 0x00000003);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x418e00, 0x00000050);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x418e08, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x418e1c, 0x00000000);
+ nv_wr32(priv, 0x418e20, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x41900c, 0x00000000);
+ nv_wr32(priv, 0x419018, 0x00000000);
+}
+
+static void
+nvc0_graph_init_tpc(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x419d08, 0x00000000);
+ nv_wr32(priv, 0x419d0c, 0x00000000);
+ nv_wr32(priv, 0x419d10, 0x00000014);
+ nv_wr32(priv, 0x419ab0, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419ac8, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc8:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419ab8, 0x000000e7);
+ nv_wr32(priv, 0x419abc, 0x00000000);
+ nv_wr32(priv, 0x419ac0, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419ab4, 0x00000000);
+ nv_wr32(priv, 0x41980c, 0x00000010);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x41980c, 0x00000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419810, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ case 0xc1:
+ nv_wr32(priv, 0x419814, 0x00000004);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x419814, 0x00000000);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419844, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x41984c, 0x0000a918);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x41984c, 0x00005bc5);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419850, 0x00000000);
+ nv_wr32(priv, 0x419854, 0x00000000);
+ nv_wr32(priv, 0x419858, 0x00000000);
+ nv_wr32(priv, 0x41985c, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419880, 0x00000002);
+ break;
+ case 0xc0:
+ case 0xc8:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419c98, 0x00000000);
+ nv_wr32(priv, 0x419ca8, 0x80000000);
+ nv_wr32(priv, 0x419cb4, 0x00000000);
+ nv_wr32(priv, 0x419cb8, 0x00008bf4);
+ nv_wr32(priv, 0x419cbc, 0x28137606);
+ nv_wr32(priv, 0x419cc0, 0x00000000);
+ nv_wr32(priv, 0x419cc4, 0x00000000);
+ nv_wr32(priv, 0x419bd4, 0x00800000);
+ nv_wr32(priv, 0x419bdc, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419bf8, 0x00000000);
+ nv_wr32(priv, 0x419bfc, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419d2c, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419d48, 0x00000000);
+ nv_wr32(priv, 0x419d4c, 0x00000000);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419c0c, 0x00000000);
+ nv_wr32(priv, 0x419e00, 0x00000000);
+ nv_wr32(priv, 0x419ea0, 0x00000000);
+ nv_wr32(priv, 0x419ea4, 0x00000100);
+ switch (nv_device(priv)->chipset) {
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419ea8, 0x02001100);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xc8:
+ case 0xce:
+ case 0xcf:
+ nv_wr32(priv, 0x419ea8, 0x00001100);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+
+ switch (nv_device(priv)->chipset) {
+ case 0xc8:
+ nv_wr32(priv, 0x419eac, 0x11100f02);
+ break;
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419eac, 0x11100702);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419eb0, 0x00000003);
+ nv_wr32(priv, 0x419eb4, 0x00000000);
+ nv_wr32(priv, 0x419eb8, 0x00000000);
+ nv_wr32(priv, 0x419ebc, 0x00000000);
+ nv_wr32(priv, 0x419ec0, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xc3:
+ case 0xc4:
+ case 0xc1:
+ case 0xce:
+ case 0xcf:
+ case 0xd9:
+ case 0xd7:
+ nv_wr32(priv, 0x419ec8, 0x0e063818);
+ nv_wr32(priv, 0x419ecc, 0x0e060e06);
+ nv_wr32(priv, 0x419ed0, 0x00003818);
+ break;
+ case 0xc0:
+ case 0xc8:
+ nv_wr32(priv, 0x419ec8, 0x06060618);
+ nv_wr32(priv, 0x419ed0, 0x0eff0e38);
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
+ nv_wr32(priv, 0x419ed4, 0x011104f1);
+ nv_wr32(priv, 0x419edc, 0x00000000);
+ nv_wr32(priv, 0x419f00, 0x00000000);
+ nv_wr32(priv, 0x419f2c, 0x00000000);
+}
+
+static void
+nvc0_graph_init_unk88xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x40880c, 0x00000000);
+ nv_wr32(priv, 0x408910, 0x00000000);
+ nv_wr32(priv, 0x408914, 0x00000000);
+ nv_wr32(priv, 0x408918, 0x00000000);
+ nv_wr32(priv, 0x40891c, 0x00000000);
+ nv_wr32(priv, 0x408920, 0x00000000);
+ nv_wr32(priv, 0x408924, 0x00000000);
+ nv_wr32(priv, 0x408928, 0x00000000);
+ nv_wr32(priv, 0x40892c, 0x00000000);
+ nv_wr32(priv, 0x408930, 0x00000000);
+ nv_wr32(priv, 0x408950, 0x00000000);
+ nv_wr32(priv, 0x408954, 0x0000ffff);
+ nv_wr32(priv, 0x408984, 0x00000000);
+ nv_wr32(priv, 0x408988, 0x08040201);
+ nv_wr32(priv, 0x40898c, 0x80402010);
+}
+
+static void
nvc0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
{
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
@@ -925,7 +1495,16 @@ nvc0_graph_init(struct nouveau_object *object)
nvc0_graph_init_obj418880(priv);
nvc0_graph_init_regs(priv);
- /*nvc0_graph_init_unitplemented_magics(priv);*/
+ nvc0_graph_init_unk40xx(priv);
+ nvc0_graph_init_unk44xx(priv);
+ nvc0_graph_init_unk78xx(priv);
+ nvc0_graph_init_unk60xx(priv);
+ nvc0_graph_init_unk64xx(priv);
+ nvc0_graph_init_unk58xx(priv);
+ nvc0_graph_init_unk80xx(priv);
+ nvc0_graph_init_gpc(priv);
+ nvc0_graph_init_tpc(priv);
+ nvc0_graph_init_unk88xx(priv);
nvc0_graph_init_gpc_0(priv);
/*nvc0_graph_init_unitplemented_c242(priv);*/
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
index c870dad0f670..af7212d96f3f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
@@ -38,8 +38,8 @@
#include <engine/fifo.h>
#include <engine/graph.h>
-#define GPC_MAX 4
-#define TPC_MAX 32
+#define GPC_MAX 32
+#define TPC_MAX (GPC_MAX * 8)
#define ROP_BCAST(r) (0x408800 + (r))
#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
@@ -124,6 +124,8 @@ nvc0_graph_class(void *obj)
case 0xe7:
case 0xe6:
return 0xa097;
+ case 0xf0:
+ return 0xa197;
default:
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
index 678c16f63055..f4685bb66eb8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
@@ -36,7 +36,6 @@ nve0_graph_sclass[] = {
{ 0xa040, &nouveau_object_ofuncs },
{ 0xa097, &nouveau_object_ofuncs },
{ 0xa0c0, &nouveau_object_ofuncs },
- { 0xa0b5, &nouveau_object_ofuncs },
{}
};
@@ -90,9 +89,9 @@ static const struct nouveau_enum nve0_mp_warp_error[] = {
{}
};
-static const struct nouveau_enum nve0_mp_global_error[] = {
- { 2, "MULTIPLE_WARP_ERRORS" },
- { 3, "OUT_OF_STACK_SPACE" },
+static const struct nouveau_bitfield nve0_mp_global_error[] = {
+ { 0x00000004, "MULTIPLE_WARP_ERRORS" },
+ { 0x00000008, "OUT_OF_STACK_SPACE" },
{}
};
@@ -122,72 +121,63 @@ static const struct nouveau_enum nve0_sked_error[] = {
};
static void
-nve0_graph_mp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
+nve0_graph_mp_trap(struct nvc0_graph_priv *priv, int gpc, int tpc)
{
- int i;
- u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x648));
- u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x650));
-
- nv_error(priv, "GPC%i/TP%i/MP trap:", gpc, tp);
+ u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x648));
+ u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x650));
- for (i = 0; i <= 31; ++i) {
- if (!(gerr & (1 << i)))
- continue;
- pr_cont(" ");
- nouveau_enum_print(nve0_mp_global_error, i);
- }
+ nv_error(priv, "GPC%i/TPC%i/MP trap:", gpc, tpc);
+ nouveau_bitfield_print(nve0_mp_global_error, gerr);
if (werr) {
pr_cont(" ");
nouveau_enum_print(nve0_mp_warp_error, werr & 0xffff);
}
pr_cont("\n");
- /* disable MP trap to avoid spam */
- nv_mask(priv, TPC_UNIT(gpc, tp, 0x50c), 0x2, 0x0);
-
- /* TODO: figure out how to resume after an MP trap */
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x648), 0x00000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x650), gerr);
}
static void
-nve0_graph_tp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
+nve0_graph_tpc_trap(struct nvc0_graph_priv *priv, int gpc, int tpc)
{
- u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x508));
+ u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x508));
if (stat & 0x1) {
- u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x224));
- nv_error(priv, "GPC%i/TP%i/TEX trap: %08x\n",
- gpc, tp, trap);
+ u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x224));
+ nv_error(priv, "GPC%i/TPC%i/TEX trap: %08x\n",
+ gpc, tpc, trap);
- nv_wr32(priv, TPC_UNIT(gpc, tp, 0x224), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
stat &= ~0x1;
}
if (stat & 0x2) {
- nve0_graph_mp_trap(priv, gpc, tp);
+ nve0_graph_mp_trap(priv, gpc, tpc);
stat &= ~0x2;
}
if (stat & 0x4) {
- u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x084));
- nv_error(priv, "GPC%i/TP%i/POLY trap: %08x\n",
- gpc, tp, trap);
+ u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x084));
+ nv_error(priv, "GPC%i/TPC%i/POLY trap: %08x\n",
+ gpc, tpc, trap);
- nv_wr32(priv, TPC_UNIT(gpc, tp, 0x084), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
stat &= ~0x4;
}
if (stat & 0x8) {
- u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x48c));
- nv_error(priv, "GPC%i/TP%i/L1C trap: %08x\n",
- gpc, tp, trap);
+ u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x48c));
+ nv_error(priv, "GPC%i/TPC%i/L1C trap: %08x\n",
+ gpc, tpc, trap);
- nv_wr32(priv, TPC_UNIT(gpc, tp, 0x48c), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
stat &= ~0x8;
}
if (stat) {
- nv_error(priv, "GPC%i/TP%i: unknown stat %08x\n",
- gpc, tp, stat);
+ nv_error(priv, "GPC%i/TPC%i: unknown stat %08x\n",
+ gpc, tpc, stat);
}
}
@@ -199,7 +189,7 @@ nve0_graph_gpc_trap(struct nvc0_graph_priv *priv)
for (gpc = 0; gpc < 4; ++gpc) {
u32 stat;
- int tp;
+ int tpc;
if (!(mask & (1 << gpc)))
continue;
@@ -258,9 +248,9 @@ nve0_graph_gpc_trap(struct nvc0_graph_priv *priv)
stat &= ~0x0008;
}
- for (tp = 0; tp < 8; ++tp) {
- if (stat & (1 << (16 + tp)))
- nve0_graph_tp_trap(priv, gpc, tp);
+ for (tpc = 0; tpc < 8; ++tpc) {
+ if (stat & (1 << (16 + tpc)))
+ nve0_graph_tpc_trap(priv, gpc, tpc);
}
stat &= ~0xff0000;
@@ -485,6 +475,7 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
case 0xe6:
priv->magic_not_rop_nr = 1;
break;
+ case 0xf0:
default:
break;
}
@@ -523,18 +514,312 @@ nve0_graph_init_regs(struct nvc0_graph_priv *priv)
}
static void
+nve0_graph_init_unk40xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x40415c, 0x00000000);
+ nv_wr32(priv, 0x404170, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x4041b4, 0x00000000);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+nve0_graph_init_unk44xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404488, 0x00000000);
+ nv_wr32(priv, 0x40448c, 0x00000000);
+}
+
+static void
+nve0_graph_init_unk78xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x407808, 0x00000000);
+}
+
+static void
+nve0_graph_init_unk60xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x406024, 0x00000000);
+}
+
+static void
+nve0_graph_init_unk64xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x4064f0, 0x00000000);
+ nv_wr32(priv, 0x4064f4, 0x00000000);
+ nv_wr32(priv, 0x4064f8, 0x00000000);
+}
+
+static void
+nve0_graph_init_unk58xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x405844, 0x00ffffff);
+ nv_wr32(priv, 0x405850, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x405900, 0x0000ff00);
+ break;
+ default:
+ nv_wr32(priv, 0x405900, 0x0000ff34);
+ break;
+ }
+ nv_wr32(priv, 0x405908, 0x00000000);
+ nv_wr32(priv, 0x405928, 0x00000000);
+ nv_wr32(priv, 0x40592c, 0x00000000);
+}
+
+static void
+nve0_graph_init_unk80xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x40803c, 0x00000000);
+}
+
+static void
+nve0_graph_init_unk70xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x407010, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x407040, 0x80440424);
+ nv_wr32(priv, 0x407048, 0x0000000a);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+nve0_graph_init_unk5bxx(struct nvc0_graph_priv *priv)
+{
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x505b44, 0x00000000);
+ break;
+ default:
+ break;
+ }
+ nv_wr32(priv, 0x405b50, 0x00000000);
+}
+
+static void
+nve0_graph_init_gpc(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x418408, 0x00000000);
+ nv_wr32(priv, 0x4184a0, 0x00000000);
+ nv_wr32(priv, 0x4184a4, 0x00000000);
+ nv_wr32(priv, 0x4184a8, 0x00000000);
+ nv_wr32(priv, 0x418604, 0x00000000);
+ nv_wr32(priv, 0x418680, 0x00000000);
+ nv_wr32(priv, 0x418714, 0x00000000);
+ nv_wr32(priv, 0x418384, 0x00000000);
+ nv_wr32(priv, 0x418814, 0x00000000);
+ nv_wr32(priv, 0x418818, 0x00000000);
+ nv_wr32(priv, 0x41881c, 0x00000000);
+ nv_wr32(priv, 0x418b04, 0x00000000);
+ nv_wr32(priv, 0x4188c8, 0x00000000);
+ nv_wr32(priv, 0x4188cc, 0x00000000);
+ nv_wr32(priv, 0x4188d0, 0x00010000);
+ nv_wr32(priv, 0x4188d4, 0x00000001);
+ nv_wr32(priv, 0x418910, 0x00010001);
+ nv_wr32(priv, 0x418914, 0x00000301);
+ nv_wr32(priv, 0x418918, 0x00800000);
+ nv_wr32(priv, 0x418980, 0x77777770);
+ nv_wr32(priv, 0x418984, 0x77777777);
+ nv_wr32(priv, 0x418988, 0x77777777);
+ nv_wr32(priv, 0x41898c, 0x77777777);
+ nv_wr32(priv, 0x418c04, 0x00000000);
+ nv_wr32(priv, 0x418c64, 0x00000000);
+ nv_wr32(priv, 0x418c68, 0x00000000);
+ nv_wr32(priv, 0x418c88, 0x00000000);
+ nv_wr32(priv, 0x418cb4, 0x00000000);
+ nv_wr32(priv, 0x418cb8, 0x00000000);
+ nv_wr32(priv, 0x418d00, 0x00000000);
+ nv_wr32(priv, 0x418d28, 0x00000000);
+ nv_wr32(priv, 0x418d2c, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x418f00, 0x00000400);
+ break;
+ default:
+ nv_wr32(priv, 0x418f00, 0x00000000);
+ break;
+ }
+ nv_wr32(priv, 0x418f08, 0x00000000);
+ nv_wr32(priv, 0x418f20, 0x00000000);
+ nv_wr32(priv, 0x418f24, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x418e00, 0x00000000);
+ break;
+ default:
+ nv_wr32(priv, 0x418e00, 0x00000060);
+ break;
+ }
+ nv_wr32(priv, 0x418e08, 0x00000000);
+ nv_wr32(priv, 0x418e1c, 0x00000000);
+ nv_wr32(priv, 0x418e20, 0x00000000);
+ nv_wr32(priv, 0x41900c, 0x00000000);
+ nv_wr32(priv, 0x419018, 0x00000000);
+}
+
+static void
+nve0_graph_init_tpc(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x419d0c, 0x00000000);
+ nv_wr32(priv, 0x419d10, 0x00000014);
+ nv_wr32(priv, 0x419ab0, 0x00000000);
+ nv_wr32(priv, 0x419ac8, 0x00000000);
+ nv_wr32(priv, 0x419ab8, 0x000000e7);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419aec, 0x00000000);
+ break;
+ default:
+ break;
+ }
+ nv_wr32(priv, 0x419abc, 0x00000000);
+ nv_wr32(priv, 0x419ac0, 0x00000000);
+ nv_wr32(priv, 0x419ab4, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419aa8, 0x00000000);
+ nv_wr32(priv, 0x419aac, 0x00000000);
+ break;
+ default:
+ break;
+ }
+ nv_wr32(priv, 0x41980c, 0x00000010);
+ nv_wr32(priv, 0x419844, 0x00000000);
+ nv_wr32(priv, 0x419850, 0x00000004);
+ nv_wr32(priv, 0x419854, 0x00000000);
+ nv_wr32(priv, 0x419858, 0x00000000);
+ nv_wr32(priv, 0x419c98, 0x00000000);
+ nv_wr32(priv, 0x419ca8, 0x00000000);
+ nv_wr32(priv, 0x419cb0, 0x01000000);
+ nv_wr32(priv, 0x419cb4, 0x00000000);
+ nv_wr32(priv, 0x419cb8, 0x00b08bea);
+ nv_wr32(priv, 0x419c84, 0x00010384);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419cbc, 0x281b3646);
+ break;
+ default:
+ nv_wr32(priv, 0x419cbc, 0x28137646);
+ break;
+ }
+ nv_wr32(priv, 0x419cc0, 0x00000000);
+ nv_wr32(priv, 0x419cc4, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419c80, 0x00020230);
+ nv_wr32(priv, 0x419ccc, 0x00000000);
+ nv_wr32(priv, 0x419cd0, 0x00000000);
+ nv_wr32(priv, 0x419c0c, 0x00000000);
+ nv_wr32(priv, 0x419e00, 0x00000080);
+ break;
+ default:
+ nv_wr32(priv, 0x419c80, 0x00020232);
+ nv_wr32(priv, 0x419c0c, 0x00000000);
+ nv_wr32(priv, 0x419e00, 0x00000000);
+ break;
+ }
+ nv_wr32(priv, 0x419ea0, 0x00000000);
+ nv_wr32(priv, 0x419ee4, 0x00000000);
+ nv_wr32(priv, 0x419ea4, 0x00000100);
+ nv_wr32(priv, 0x419ea8, 0x00000000);
+ nv_wr32(priv, 0x419eb4, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ break;
+ default:
+ nv_wr32(priv, 0x419eb8, 0x00000000);
+ break;
+ }
+ nv_wr32(priv, 0x419ebc, 0x00000000);
+ nv_wr32(priv, 0x419ec0, 0x00000000);
+ nv_wr32(priv, 0x419edc, 0x00000000);
+ nv_wr32(priv, 0x419f00, 0x00000000);
+ switch (nv_device(priv)->chipset) {
+ case 0xf0:
+ nv_wr32(priv, 0x419ed0, 0x00003234);
+ nv_wr32(priv, 0x419f74, 0x00015555);
+ nv_wr32(priv, 0x419f80, 0x00000000);
+ nv_wr32(priv, 0x419f84, 0x00000000);
+ nv_wr32(priv, 0x419f88, 0x00000000);
+ nv_wr32(priv, 0x419f8c, 0x00000000);
+ break;
+ default:
+ nv_wr32(priv, 0x419f74, 0x00000555);
+ break;
+ }
+}
+
+static void
+nve0_graph_init_tpcunk(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x41be04, 0x00000000);
+ nv_wr32(priv, 0x41be08, 0x00000004);
+ nv_wr32(priv, 0x41be0c, 0x00000000);
+ nv_wr32(priv, 0x41be10, 0x003b8bc7);
+ nv_wr32(priv, 0x41be14, 0x00000000);
+ nv_wr32(priv, 0x41be18, 0x00000000);
+ nv_wr32(priv, 0x41bfd4, 0x00800000);
+ nv_wr32(priv, 0x41bfdc, 0x00000000);
+ nv_wr32(priv, 0x41bff8, 0x00000000);
+ nv_wr32(priv, 0x41bffc, 0x00000000);
+ nv_wr32(priv, 0x41becc, 0x00000000);
+ nv_wr32(priv, 0x41bee8, 0x00000000);
+ nv_wr32(priv, 0x41beec, 0x00000000);
+}
+
+static void
+nve0_graph_init_unk88xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x40880c, 0x00000000);
+ nv_wr32(priv, 0x408850, 0x00000004);
+ nv_wr32(priv, 0x408910, 0x00000000);
+ nv_wr32(priv, 0x408914, 0x00000000);
+ nv_wr32(priv, 0x408918, 0x00000000);
+ nv_wr32(priv, 0x40891c, 0x00000000);
+ nv_wr32(priv, 0x408920, 0x00000000);
+ nv_wr32(priv, 0x408924, 0x00000000);
+ nv_wr32(priv, 0x408928, 0x00000000);
+ nv_wr32(priv, 0x40892c, 0x00000000);
+ nv_wr32(priv, 0x408930, 0x00000000);
+ nv_wr32(priv, 0x408950, 0x00000000);
+ nv_wr32(priv, 0x408954, 0x0000ffff);
+ nv_wr32(priv, 0x408958, 0x00000034);
+ nv_wr32(priv, 0x408984, 0x00000000);
+ nv_wr32(priv, 0x408988, 0x08040201);
+ nv_wr32(priv, 0x40898c, 0x80402010);
+}
+
+static void
nve0_graph_init_units(struct nvc0_graph_priv *priv)
{
nv_wr32(priv, 0x409ffc, 0x00000000);
nv_wr32(priv, 0x409c14, 0x00003e3e);
- nv_wr32(priv, 0x409c24, 0x000f0000);
+ switch (nv_device(priv)->chipset) {
+ case 0xe4:
+ case 0xe7:
+ case 0xe6:
+ nv_wr32(priv, 0x409c24, 0x000f0001);
+ break;
+ case 0xf0:
+ nv_wr32(priv, 0x409c24, 0x000f0000);
+ break;
+ }
nv_wr32(priv, 0x404000, 0xc0000000);
nv_wr32(priv, 0x404600, 0xc0000000);
nv_wr32(priv, 0x408030, 0xc0000000);
nv_wr32(priv, 0x404490, 0xc0000000);
nv_wr32(priv, 0x406018, 0xc0000000);
- nv_wr32(priv, 0x407020, 0xc0000000);
+ nv_wr32(priv, 0x407020, 0x40000000);
nv_wr32(priv, 0x405840, 0xc0000000);
nv_wr32(priv, 0x405844, 0x00ffffff);
@@ -770,6 +1055,19 @@ nve0_graph_init(struct nouveau_object *object)
nve0_graph_init_obj418880(priv);
nve0_graph_init_regs(priv);
+ nve0_graph_init_unk40xx(priv);
+ nve0_graph_init_unk44xx(priv);
+ nve0_graph_init_unk78xx(priv);
+ nve0_graph_init_unk60xx(priv);
+ nve0_graph_init_unk64xx(priv);
+ nve0_graph_init_unk58xx(priv);
+ nve0_graph_init_unk80xx(priv);
+ nve0_graph_init_unk70xx(priv);
+ nve0_graph_init_unk5bxx(priv);
+ nve0_graph_init_gpc(priv);
+ nve0_graph_init_tpc(priv);
+ nve0_graph_init_tpcunk(priv);
+ nve0_graph_init_unk88xx(priv);
nve0_graph_init_gpc_0(priv);
nv_wr32(priv, 0x400500, 0x00010001);
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c
index bc7d12b30fc1..37a2bd9e8078 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c
@@ -125,13 +125,6 @@ nv50_mpeg_cclass = {
* PMPEG engine/subdev functions
******************************************************************************/
-int
-nv50_mpeg_tlb_flush(struct nouveau_engine *engine)
-{
- nv50_vm_flush_engine(&engine->base, 0x08);
- return 0;
-}
-
void
nv50_mpeg_intr(struct nouveau_subdev *subdev)
{
@@ -191,7 +184,6 @@ nv50_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv50_vpe_intr;
nv_engine(priv)->cclass = &nv50_mpeg_cclass;
nv_engine(priv)->sclass = nv50_mpeg_sclass;
- nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c
index 8f805b44d59e..96f5aa92677b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c
@@ -88,7 +88,6 @@ nv84_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv50_mpeg_intr;
nv_engine(priv)->cclass = &nv84_mpeg_cclass;
nv_engine(priv)->sclass = nv84_mpeg_sclass;
- nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c
index ebf0d860e2dd..98072c1ff360 100644
--- a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c
@@ -22,8 +22,7 @@
* Authors: Maarten Lankhorst
*/
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
#include <engine/ppp.h>
struct nvc0_ppp_priv {
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c
index 261cd96e6951..fd6272b8cdb2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c
@@ -19,24 +19,19 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs, Ilia Mirkin
*/
-#include <core/engctx.h>
-#include <core/class.h>
-
+#include <engine/xtensa.h>
#include <engine/vp.h>
-struct nv84_vp_priv {
- struct nouveau_engine base;
-};
-
/*******************************************************************************
* VP object classes
******************************************************************************/
static struct nouveau_oclass
nv84_vp_sclass[] = {
+ { 0x7476, &nouveau_object_ofuncs },
{},
};
@@ -48,7 +43,7 @@ static struct nouveau_oclass
nv84_vp_cclass = {
.handle = NV_ENGCTX(VP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_engctx_ctor,
+ .ctor = _nouveau_xtensa_engctx_ctor,
.dtor = _nouveau_engctx_dtor,
.init = _nouveau_engctx_init,
.fini = _nouveau_engctx_fini,
@@ -66,10 +61,10 @@ nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv84_vp_priv *priv;
+ struct nouveau_xtensa *priv;
int ret;
- ret = nouveau_engine_create(parent, engine, oclass, true,
+ ret = nouveau_xtensa_create(parent, engine, oclass, 0xf000, true,
"PVP", "vp", &priv);
*pobject = nv_object(priv);
if (ret)
@@ -78,6 +73,8 @@ nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->unit = 0x01020000;
nv_engine(priv)->cclass = &nv84_vp_cclass;
nv_engine(priv)->sclass = nv84_vp_sclass;
+ priv->fifo_val = 0x111;
+ priv->unkd28 = 0x9c544;
return 0;
}
@@ -86,8 +83,10 @@ nv84_vp_oclass = {
.handle = NV_ENGINE(VP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_vp_ctor,
- .dtor = _nouveau_engine_dtor,
- .init = _nouveau_engine_init,
- .fini = _nouveau_engine_fini,
+ .dtor = _nouveau_xtensa_dtor,
+ .init = _nouveau_xtensa_init,
+ .fini = _nouveau_xtensa_fini,
+ .rd32 = _nouveau_xtensa_rd32,
+ .wr32 = _nouveau_xtensa_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c b/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c
new file mode 100644
index 000000000000..8a8236bc84de
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/engctx.h>
+#include <core/class.h>
+
+#include <engine/vp.h>
+
+struct nv98_vp_priv {
+ struct nouveau_engine base;
+};
+
+/*******************************************************************************
+ * VP object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_vp_sclass[] = {
+ {},
+};
+
+/*******************************************************************************
+ * PVP context
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_vp_cclass = {
+ .handle = NV_ENGCTX(VP, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = _nouveau_engctx_ctor,
+ .dtor = _nouveau_engctx_dtor,
+ .init = _nouveau_engctx_init,
+ .fini = _nouveau_engctx_fini,
+ .rd32 = _nouveau_engctx_rd32,
+ .wr32 = _nouveau_engctx_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PVP engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv98_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_vp_priv *priv;
+ int ret;
+
+ ret = nouveau_engine_create(parent, engine, oclass, true,
+ "PVP", "vp", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x01020000;
+ nv_engine(priv)->cclass = &nv98_vp_cclass;
+ nv_engine(priv)->sclass = nv98_vp_sclass;
+ return 0;
+}
+
+struct nouveau_oclass
+nv98_vp_oclass = {
+ .handle = NV_ENGINE(VP, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_vp_ctor,
+ .dtor = _nouveau_engine_dtor,
+ .init = _nouveau_engine_init,
+ .fini = _nouveau_engine_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c
index f761949d7039..1879229b60eb 100644
--- a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c
@@ -22,8 +22,7 @@
* Authors: Maarten Lankhorst
*/
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
#include <engine/vp.h>
struct nvc0_vp_priv {
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c
index 2384ce5dbe16..d28ecbf7bc49 100644
--- a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c
@@ -22,8 +22,7 @@
* Authors: Ben Skeggs
*/
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
#include <engine/vp.h>
struct nve0_vp_priv {
diff --git a/drivers/gpu/drm/nouveau/core/engine/xtensa.c b/drivers/gpu/drm/nouveau/core/engine/xtensa.c
new file mode 100644
index 000000000000..0639bc59d0a5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/xtensa.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2013 Ilia Mirkin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <engine/xtensa.h>
+
+u32
+_nouveau_xtensa_rd32(struct nouveau_object *object, u64 addr)
+{
+ struct nouveau_xtensa *xtensa = (void *)object;
+ return nv_rd32(xtensa, xtensa->addr + addr);
+}
+
+void
+_nouveau_xtensa_wr32(struct nouveau_object *object, u64 addr, u32 data)
+{
+ struct nouveau_xtensa *xtensa = (void *)object;
+ nv_wr32(xtensa, xtensa->addr + addr, data);
+}
+
+int
+_nouveau_xtensa_engctx_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_engctx *engctx;
+ int ret;
+
+ ret = nouveau_engctx_create(parent, engine, oclass, NULL,
+ 0x10000, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &engctx);
+ *pobject = nv_object(engctx);
+ return ret;
+}
+
+void
+_nouveau_xtensa_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_xtensa *xtensa = (void *)subdev;
+ u32 unk104 = nv_ro32(xtensa, 0xd04);
+ u32 intr = nv_ro32(xtensa, 0xc20);
+ u32 chan = nv_ro32(xtensa, 0xc28);
+ u32 unk10c = nv_ro32(xtensa, 0xd0c);
+
+ if (intr & 0x10)
+ nv_warn(xtensa, "Watchdog interrupt, engine hung.\n");
+ nv_wo32(xtensa, 0xc20, intr);
+ intr = nv_ro32(xtensa, 0xc20);
+ if (unk104 == 0x10001 && unk10c == 0x200 && chan && !intr) {
+ nv_debug(xtensa, "Enabling FIFO_CTRL\n");
+ nv_mask(xtensa, xtensa->addr + 0xd94, 0, xtensa->fifo_val);
+ }
+}
+
+int
+nouveau_xtensa_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, u32 addr, bool enable,
+ const char *iname, const char *fname,
+ int length, void **pobject)
+{
+ struct nouveau_xtensa *xtensa;
+ int ret;
+
+ ret = nouveau_engine_create_(parent, engine, oclass, enable, iname,
+ fname, length, pobject);
+ xtensa = *pobject;
+ if (ret)
+ return ret;
+
+ nv_subdev(xtensa)->intr = _nouveau_xtensa_intr;
+
+ xtensa->addr = addr;
+
+ return 0;
+}
+
+int
+_nouveau_xtensa_init(struct nouveau_object *object)
+{
+ struct nouveau_device *device = nv_device(object);
+ struct nouveau_xtensa *xtensa = (void *)object;
+ const struct firmware *fw;
+ char name[32];
+ int i, ret;
+ u32 tmp;
+
+ ret = nouveau_engine_init(&xtensa->base);
+ if (ret)
+ return ret;
+
+ if (!xtensa->gpu_fw) {
+ snprintf(name, sizeof(name), "nouveau/nv84_xuc%03x",
+ xtensa->addr >> 12);
+
+ ret = request_firmware(&fw, name, &device->pdev->dev);
+ if (ret) {
+ nv_warn(xtensa, "unable to load firmware %s\n", name);
+ return ret;
+ }
+
+ ret = nouveau_gpuobj_new(object, NULL, fw->size, 0x1000, 0,
+ &xtensa->gpu_fw);
+ if (ret) {
+ release_firmware(fw);
+ return ret;
+ }
+
+ nv_debug(xtensa, "Loading firmware to address: 0x%llx\n",
+ xtensa->gpu_fw->addr);
+
+ for (i = 0; i < fw->size / 4; i++)
+ nv_wo32(xtensa->gpu_fw, i * 4, *((u32 *)fw->data + i));
+ release_firmware(fw);
+ }
+
+ nv_wo32(xtensa, 0xd10, 0x1fffffff); /* ?? */
+ nv_wo32(xtensa, 0xd08, 0x0fffffff); /* ?? */
+
+ nv_wo32(xtensa, 0xd28, xtensa->unkd28); /* ?? */
+ nv_wo32(xtensa, 0xc20, 0x3f); /* INTR */
+ nv_wo32(xtensa, 0xd84, 0x3f); /* INTR_EN */
+
+ nv_wo32(xtensa, 0xcc0, xtensa->gpu_fw->addr >> 8); /* XT_REGION_BASE */
+ nv_wo32(xtensa, 0xcc4, 0x1c); /* XT_REGION_SETUP */
+ nv_wo32(xtensa, 0xcc8, xtensa->gpu_fw->size >> 8); /* XT_REGION_LIMIT */
+
+ tmp = nv_rd32(xtensa, 0x0);
+ nv_wo32(xtensa, 0xde0, tmp); /* SCRATCH_H2X */
+
+ nv_wo32(xtensa, 0xce8, 0xf); /* XT_REGION_SETUP */
+
+ nv_wo32(xtensa, 0xc20, 0x3f); /* INTR */
+ nv_wo32(xtensa, 0xd84, 0x3f); /* INTR_EN */
+
+ return 0;
+}
+
+int
+_nouveau_xtensa_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nouveau_xtensa *xtensa = (void *)object;
+
+ nv_wo32(xtensa, 0xd84, 0); /* INTR_EN */
+ nv_wo32(xtensa, 0xd94, 0); /* FIFO_CTRL */
+
+ if (!suspend)
+ nouveau_gpuobj_ref(NULL, &xtensa->gpu_fw);
+
+ return nouveau_engine_fini(&xtensa->base, suspend);
+}
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
index 05840f3eee98..99b6600fe80a 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -17,8 +17,7 @@ enum nv_subdev_type {
NVDEV_SUBDEV_DEVINIT,
NVDEV_SUBDEV_GPIO,
NVDEV_SUBDEV_I2C,
- NVDEV_SUBDEV_CLOCK,
- NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_CLOCK,
+ NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_I2C,
/* This grouping of subdevs are initialised right after they've
* been created, and are allowed to assume any subdevs in the
@@ -35,6 +34,7 @@ enum nv_subdev_type {
NVDEV_SUBDEV_VM,
NVDEV_SUBDEV_BAR,
NVDEV_SUBDEV_VOLT,
+ NVDEV_SUBDEV_CLOCK,
NVDEV_SUBDEV_THERM,
NVDEV_ENGINE_DMAOBJ,
@@ -49,6 +49,7 @@ enum nv_subdev_type {
NVDEV_ENGINE_PPP,
NVDEV_ENGINE_COPY0,
NVDEV_ENGINE_COPY1,
+ NVDEV_ENGINE_COPY2,
NVDEV_ENGINE_UNK1C1,
NVDEV_ENGINE_VENC,
NVDEV_ENGINE_DISP,
diff --git a/drivers/gpu/drm/nouveau/core/include/core/mm.h b/drivers/gpu/drm/nouveau/core/include/core/mm.h
index 2514e81ade02..2bf7d0e32261 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/mm.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/mm.h
@@ -15,8 +15,6 @@ struct nouveau_mm {
struct list_head nodes;
struct list_head free;
- struct mutex mutex;
-
u32 block_size;
int heap_nodes;
};
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/bsp.h b/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
index 13ccdf54dfad..67662e2c4547 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
@@ -2,6 +2,7 @@
#define __NOUVEAU_BSP_H__
extern struct nouveau_oclass nv84_bsp_oclass;
+extern struct nouveau_oclass nv98_bsp_oclass;
extern struct nouveau_oclass nvc0_bsp_oclass;
extern struct nouveau_oclass nve0_bsp_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/copy.h b/drivers/gpu/drm/nouveau/core/include/engine/copy.h
index 8cad2cf28cef..316a28ae5f5c 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/copy.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/copy.h
@@ -8,5 +8,6 @@ extern struct nouveau_oclass nvc0_copy0_oclass;
extern struct nouveau_oclass nvc0_copy1_oclass;
extern struct nouveau_oclass nve0_copy0_oclass;
extern struct nouveau_oclass nve0_copy1_oclass;
+extern struct nouveau_oclass nve0_copy2_oclass;
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/falcon.h b/drivers/gpu/drm/nouveau/core/include/engine/falcon.h
index 1edec386ab36..1edec386ab36 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/falcon.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/falcon.h
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
index bbf0d4a5bbd7..1d1a89a06ee4 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
@@ -54,7 +54,6 @@ extern struct nouveau_ofuncs nv50_mpeg_ofuncs;
int nv50_mpeg_context_ctor(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, void *, u32,
struct nouveau_object **);
-int nv50_mpeg_tlb_flush(struct nouveau_engine *);
void nv50_mpeg_intr(struct nouveau_subdev *);
int nv50_mpeg_init(struct nouveau_object *);
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/vp.h b/drivers/gpu/drm/nouveau/core/include/engine/vp.h
index d7b287b115bf..39baebec7fbb 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/vp.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/vp.h
@@ -2,6 +2,7 @@
#define __NOUVEAU_VP_H__
extern struct nouveau_oclass nv84_vp_oclass;
+extern struct nouveau_oclass nv98_vp_oclass;
extern struct nouveau_oclass nvc0_vp_oclass;
extern struct nouveau_oclass nve0_vp_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h b/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h
new file mode 100644
index 000000000000..306100f31f02
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h
@@ -0,0 +1,38 @@
+#ifndef __NOUVEAU_XTENSA_H__
+#define __NOUVEAU_XTENSA_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+#include <core/gpuobj.h>
+
+struct nouveau_xtensa {
+ struct nouveau_engine base;
+
+ u32 addr;
+ struct nouveau_gpuobj *gpu_fw;
+ u32 fifo_val;
+ u32 unkd28;
+};
+
+#define nouveau_xtensa_create(p,e,c,b,d,i,f,r) \
+ nouveau_xtensa_create_((p), (e), (c), (b), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+
+int _nouveau_xtensa_engctx_ctor(struct nouveau_object *,
+ struct nouveau_object *,
+ struct nouveau_oclass *, void *, u32,
+ struct nouveau_object **);
+
+void _nouveau_xtensa_intr(struct nouveau_subdev *);
+int nouveau_xtensa_create_(struct nouveau_object *,
+ struct nouveau_object *,
+ struct nouveau_oclass *, u32, bool,
+ const char *, const char *,
+ int, void **);
+#define _nouveau_xtensa_dtor _nouveau_engine_dtor
+int _nouveau_xtensa_init(struct nouveau_object *);
+int _nouveau_xtensa_fini(struct nouveau_object *, bool);
+u32 _nouveau_xtensa_rd32(struct nouveau_object *, u64);
+void _nouveau_xtensa_wr32(struct nouveau_object *, u64, u32);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
index 41b7a6a76f19..89ee289097a6 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
@@ -10,8 +10,6 @@ struct nvbios_pll;
struct nouveau_clock {
struct nouveau_subdev base;
- int (*pll_set)(struct nouveau_clock *, u32 type, u32 freq);
-
/*XXX: die, these are here *only* to support the completely
* bat-shit insane what-was-nouveau_hw.c code
*/
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
index 29e4cc1f6cc0..685c9b12ee4c 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
@@ -8,6 +8,8 @@ struct nouveau_devinit {
struct nouveau_subdev base;
bool post;
void (*meminit)(struct nouveau_devinit *);
+ int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq);
+
};
static inline struct nouveau_devinit *
@@ -20,11 +22,20 @@ nouveau_devinit(void *obj)
nouveau_devinit_create_((p), (e), (o), sizeof(**d), (void **)d)
#define nouveau_devinit_destroy(p) \
nouveau_subdev_destroy(&(p)->base)
+#define nouveau_devinit_init(p) ({ \
+ struct nouveau_devinit *d = (p); \
+ _nouveau_devinit_init(nv_object(d)); \
+})
+#define nouveau_devinit_fini(p,s) ({ \
+ struct nouveau_devinit *d = (p); \
+ _nouveau_devinit_fini(nv_object(d), (s)); \
+})
int nouveau_devinit_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, int, void **);
-int nouveau_devinit_init(struct nouveau_devinit *);
-int nouveau_devinit_fini(struct nouveau_devinit *, bool suspend);
+#define _nouveau_devinit_dtor _nouveau_subdev_dtor
+int _nouveau_devinit_init(struct nouveau_object *);
+int _nouveau_devinit_fini(struct nouveau_object *, bool suspend);
extern struct nouveau_oclass nv04_devinit_oclass;
extern struct nouveau_oclass nv05_devinit_oclass;
@@ -32,9 +43,7 @@ extern struct nouveau_oclass nv10_devinit_oclass;
extern struct nouveau_oclass nv1a_devinit_oclass;
extern struct nouveau_oclass nv20_devinit_oclass;
extern struct nouveau_oclass nv50_devinit_oclass;
-
-void nv04_devinit_dtor(struct nouveau_object *);
-int nv04_devinit_init(struct nouveau_object *);
-int nv04_devinit_fini(struct nouveau_object *, bool);
+extern struct nouveau_oclass nva3_devinit_oclass;
+extern struct nouveau_oclass nvc0_devinit_oclass;
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
index da470e6851b1..2e7405084261 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -53,31 +53,7 @@ struct nouveau_fb {
bool (*memtype_valid)(struct nouveau_fb *, u32 memtype);
- struct {
- enum {
- NV_MEM_TYPE_UNKNOWN = 0,
- NV_MEM_TYPE_STOLEN,
- NV_MEM_TYPE_SGRAM,
- NV_MEM_TYPE_SDRAM,
- NV_MEM_TYPE_DDR1,
- NV_MEM_TYPE_DDR2,
- NV_MEM_TYPE_DDR3,
- NV_MEM_TYPE_GDDR2,
- NV_MEM_TYPE_GDDR3,
- NV_MEM_TYPE_GDDR4,
- NV_MEM_TYPE_GDDR5
- } type;
- u64 stolen;
- u64 size;
-
- int ranks;
- int parts;
-
- int (*init)(struct nouveau_fb *);
- int (*get)(struct nouveau_fb *, u64 size, u32 align,
- u32 size_nc, u32 type, struct nouveau_mem **);
- void (*put)(struct nouveau_fb *, struct nouveau_mem **);
- } ram;
+ struct nouveau_ram *ram;
struct nouveau_mm vram;
struct nouveau_mm tags;
@@ -102,18 +78,6 @@ nouveau_fb(void *obj)
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
}
-#define nouveau_fb_create(p,e,c,d) \
- nouveau_subdev_create((p), (e), (c), 0, "PFB", "fb", (d))
-int nouveau_fb_preinit(struct nouveau_fb *);
-void nouveau_fb_destroy(struct nouveau_fb *);
-int nouveau_fb_init(struct nouveau_fb *);
-#define nouveau_fb_fini(p,s) \
- nouveau_subdev_fini(&(p)->base, (s))
-
-void _nouveau_fb_dtor(struct nouveau_object *);
-int _nouveau_fb_init(struct nouveau_object *);
-#define _nouveau_fb_fini _nouveau_subdev_fini
-
extern struct nouveau_oclass nv04_fb_oclass;
extern struct nouveau_oclass nv10_fb_oclass;
extern struct nouveau_oclass nv1a_fb_oclass;
@@ -132,40 +96,31 @@ extern struct nouveau_oclass nv4e_fb_oclass;
extern struct nouveau_oclass nv50_fb_oclass;
extern struct nouveau_oclass nvc0_fb_oclass;
-struct nouveau_bios;
-int nouveau_fb_bios_memtype(struct nouveau_bios *);
-
-bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
-
-void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
-void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
-void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int nv20_fb_vram_init(struct nouveau_fb *);
-void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
-void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
-void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int nv30_fb_init(struct nouveau_object *);
-void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
-
-void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *);
-
-int nv41_fb_vram_init(struct nouveau_fb *);
-int nv41_fb_init(struct nouveau_object *);
-void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int nv44_fb_vram_init(struct nouveau_fb *);
-int nv44_fb_init(struct nouveau_object *);
-void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+struct nouveau_ram {
+ struct nouveau_object base;
+ enum {
+ NV_MEM_TYPE_UNKNOWN = 0,
+ NV_MEM_TYPE_STOLEN,
+ NV_MEM_TYPE_SGRAM,
+ NV_MEM_TYPE_SDRAM,
+ NV_MEM_TYPE_DDR1,
+ NV_MEM_TYPE_DDR2,
+ NV_MEM_TYPE_DDR3,
+ NV_MEM_TYPE_GDDR2,
+ NV_MEM_TYPE_GDDR3,
+ NV_MEM_TYPE_GDDR4,
+ NV_MEM_TYPE_GDDR5
+ } type;
+ u64 stolen;
+ u64 size;
+ u32 tags;
-void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
+ int ranks;
+ int parts;
-void nv50_fb_vram_del(struct nouveau_fb *, struct nouveau_mem **);
+ int (*get)(struct nouveau_fb *, u64 size, u32 align,
+ u32 size_nc, u32 type, struct nouveau_mem **);
+ void (*put)(struct nouveau_fb *, struct nouveau_mem **);
+};
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
index 9d595efe667a..f2e87b105666 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
@@ -58,7 +58,7 @@ struct nouveau_vm {
int refcount;
struct list_head pgd_list;
- atomic_t engref[64]; //NVDEV_SUBDEV_NR];
+ atomic_t engref[NVDEV_SUBDEV_NR];
struct nouveau_vm_pgt *pgt;
u32 fpde;
@@ -117,9 +117,6 @@ int nv04_vm_create(struct nouveau_vmmgr *, u64, u64, u64,
struct nouveau_vm **);
void nv04_vmmgr_dtor(struct nouveau_object *);
-void nv50_vm_flush_engine(struct nouveau_subdev *, int engine);
-void nvc0_vm_flush_engine(struct nouveau_subdev *, u64 addr, int type);
-
/* nouveau_vm.c */
int nouveau_vm_create(struct nouveau_vmmgr *, u64 offset, u64 length,
u64 mm_offset, u32 block, struct nouveau_vm **);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
index 649f1ced1fe0..160d27f3c7b4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
@@ -53,7 +53,6 @@ nv50_bar_kmap(struct nouveau_bar *bar, struct nouveau_mem *mem,
return ret;
nouveau_vm_map(vma, mem);
- nv50_vm_flush_engine(nv_subdev(bar), 6);
return 0;
}
@@ -69,7 +68,6 @@ nv50_bar_umap(struct nouveau_bar *bar, struct nouveau_mem *mem,
return ret;
nouveau_vm_map(vma, mem);
- nv50_vm_flush_engine(nv_subdev(bar), 6);
return 0;
}
@@ -77,7 +75,6 @@ static void
nv50_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
{
nouveau_vm_unmap(vma);
- nv50_vm_flush_engine(nv_subdev(bar), 6);
nouveau_vm_put(vma);
}
@@ -147,6 +144,8 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
+ atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
ret = nouveau_gpuobj_new(nv_object(priv), heap,
((limit-- - start) >> 12) * 8, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC, &vm->pgt[0].obj[0]);
@@ -179,6 +178,8 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
+ atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
ret = nouveau_vm_ref(vm, &priv->bar1_vm, priv->pgd);
nouveau_vm_ref(NULL, &vm, NULL);
if (ret)
@@ -237,7 +238,11 @@ nv50_bar_init(struct nouveau_object *object)
nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
- nv50_vm_flush_engine(nv_subdev(priv), 6);
+ nv_wr32(priv, 0x100c80, 0x00060001);
+ if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000)) {
+ nv_error(priv, "vm flush timeout\n");
+ return -EBUSY;
+ }
nv_wr32(priv, 0x001704, 0x00000000 | priv->mem->addr >> 12);
nv_wr32(priv, 0x001704, 0x40000000 | priv->mem->addr >> 12);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
index f8a44956dec1..b2ec7411eb2e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
@@ -51,7 +51,6 @@ nvc0_bar_kmap(struct nouveau_bar *bar, struct nouveau_mem *mem,
return ret;
nouveau_vm_map(vma, mem);
- nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[0].pgd->addr, 5);
return 0;
}
@@ -68,18 +67,13 @@ nvc0_bar_umap(struct nouveau_bar *bar, struct nouveau_mem *mem,
return ret;
nouveau_vm_map(vma, mem);
- nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[1].pgd->addr, 5);
return 0;
}
static void
nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
{
- struct nvc0_bar_priv *priv = (void *)bar;
- int i = !(vma->vm == priv->bar[0].vm);
-
nouveau_vm_unmap(vma);
- nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[i].pgd->addr, 5);
nouveau_vm_put(vma);
}
@@ -116,6 +110,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
+ atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
(pci_resource_len(pdev, 3) >> 12) * 8,
0x1000, NVOBJ_FLAG_ZERO_ALLOC,
@@ -150,6 +146,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
+ atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd);
nouveau_vm_ref(NULL, &vm, NULL);
if (ret)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index 0e2c1a4f1659..aa0fbbec7f08 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -85,11 +85,15 @@ static void
nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
{
struct nouveau_device *device = nv_device(bios);
+ u64 addr = 0;
u32 bar0 = 0;
int i;
if (device->card_type >= NV_50) {
- u64 addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8;
+ if ( device->card_type < NV_C0 ||
+ !(nv_rd32(bios, 0x022500) & 0x00000001))
+ addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8;
+
if (!addr) {
addr = (u64)nv_rd32(bios, 0x001700) << 16;
addr += 0xf0000;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index c434d398d16f..0687e6481438 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -10,7 +10,6 @@
#include <subdev/bios/gpio.h>
#include <subdev/bios/init.h>
#include <subdev/devinit.h>
-#include <subdev/clock.h>
#include <subdev/i2c.h>
#include <subdev/vga.h>
#include <subdev/gpio.h>
@@ -300,9 +299,9 @@ init_wrauxr(struct nvbios_init *init, u32 addr, u8 data)
static void
init_prog_pll(struct nvbios_init *init, u32 id, u32 freq)
{
- struct nouveau_clock *clk = nouveau_clock(init->bios);
- if (clk && clk->pll_set && init_exec(init)) {
- int ret = clk->pll_set(clk, id, freq);
+ struct nouveau_devinit *devinit = nouveau_devinit(init->bios);
+ if (devinit->pll_set && init_exec(init)) {
+ int ret = devinit->pll_set(devinit, id, freq);
if (ret)
warn("failed to prog pll 0x%08x to %dkHz\n", id, freq);
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
index b7fd1151166e..a14277586595 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
@@ -22,9 +22,10 @@
* Authors: Ben Skeggs
*/
-#include <subdev/clock.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/devinit/priv.h>
#include "pll.h"
@@ -32,272 +33,12 @@ struct nv04_clock_priv {
struct nouveau_clock base;
};
-static int
-powerctrl_1_shift(int chip_version, int reg)
-{
- int shift = -4;
-
- if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
- return shift;
-
- switch (reg) {
- case 0x680520:
- shift += 4;
- case 0x680508:
- shift += 4;
- case 0x680504:
- shift += 4;
- case 0x680500:
- shift += 4;
- }
-
- /*
- * the shift for vpll regs is only used for nv3x chips with a single
- * stage pll
- */
- if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
- chip_version == 0x36 || chip_version >= 0x40))
- shift = -4;
-
- return shift;
-}
-
-static void
-setPLL_single(struct nv04_clock_priv *priv, u32 reg,
- struct nouveau_pll_vals *pv)
-{
- int chip_version = nouveau_bios(priv)->version.chip;
- uint32_t oldpll = nv_rd32(priv, reg);
- int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
- uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
- uint32_t saved_powerctrl_1 = 0;
- int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
-
- if (oldpll == pll)
- return; /* already set */
-
- if (shift_powerctrl_1 >= 0) {
- saved_powerctrl_1 = nv_rd32(priv, 0x001584);
- nv_wr32(priv, 0x001584,
- (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
- 1 << shift_powerctrl_1);
- }
-
- if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
- /* upclock -- write new post divider first */
- nv_wr32(priv, reg, pv->log2P << 16 | (oldpll & 0xffff));
- else
- /* downclock -- write new NM first */
- nv_wr32(priv, reg, (oldpll & 0xffff0000) | pv->NM1);
-
- if (chip_version < 0x17 && chip_version != 0x11)
- /* wait a bit on older chips */
- msleep(64);
- nv_rd32(priv, reg);
-
- /* then write the other half as well */
- nv_wr32(priv, reg, pll);
-
- if (shift_powerctrl_1 >= 0)
- nv_wr32(priv, 0x001584, saved_powerctrl_1);
-}
-
-static uint32_t
-new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
-{
- bool head_a = (reg1 == 0x680508);
-
- if (ss) /* single stage pll mode */
- ramdac580 |= head_a ? 0x00000100 : 0x10000000;
- else
- ramdac580 &= head_a ? 0xfffffeff : 0xefffffff;
-
- return ramdac580;
-}
-
-static void
-setPLL_double_highregs(struct nv04_clock_priv *priv, u32 reg1,
- struct nouveau_pll_vals *pv)
-{
- int chip_version = nouveau_bios(priv)->version.chip;
- bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
- uint32_t reg2 = reg1 + ((reg1 == 0x680520) ? 0x5c : 0x70);
- uint32_t oldpll1 = nv_rd32(priv, reg1);
- uint32_t oldpll2 = !nv3035 ? nv_rd32(priv, reg2) : 0;
- uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
- uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
- uint32_t oldramdac580 = 0, ramdac580 = 0;
- bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */
- uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
- int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
-
- /* model specific additions to generic pll1 and pll2 set up above */
- if (nv3035) {
- pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
- (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
- pll2 = 0;
- }
- if (chip_version > 0x40 && reg1 >= 0x680508) { /* !nv40 */
- oldramdac580 = nv_rd32(priv, 0x680580);
- ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
- if (oldramdac580 != ramdac580)
- oldpll1 = ~0; /* force mismatch */
- if (single_stage)
- /* magic value used by nvidia in single stage mode */
- pll2 |= 0x011f;
- }
- if (chip_version > 0x70)
- /* magic bits set by the blob (but not the bios) on g71-73 */
- pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
-
- if (oldpll1 == pll1 && oldpll2 == pll2)
- return; /* already set */
-
- if (shift_powerctrl_1 >= 0) {
- saved_powerctrl_1 = nv_rd32(priv, 0x001584);
- nv_wr32(priv, 0x001584,
- (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
- 1 << shift_powerctrl_1);
- }
-
- if (chip_version >= 0x40) {
- int shift_c040 = 14;
-
- switch (reg1) {
- case 0x680504:
- shift_c040 += 2;
- case 0x680500:
- shift_c040 += 2;
- case 0x680520:
- shift_c040 += 2;
- case 0x680508:
- shift_c040 += 2;
- }
-
- savedc040 = nv_rd32(priv, 0xc040);
- if (shift_c040 != 14)
- nv_wr32(priv, 0xc040, savedc040 & ~(3 << shift_c040));
- }
-
- if (oldramdac580 != ramdac580)
- nv_wr32(priv, 0x680580, ramdac580);
-
- if (!nv3035)
- nv_wr32(priv, reg2, pll2);
- nv_wr32(priv, reg1, pll1);
-
- if (shift_powerctrl_1 >= 0)
- nv_wr32(priv, 0x001584, saved_powerctrl_1);
- if (chip_version >= 0x40)
- nv_wr32(priv, 0xc040, savedc040);
-}
-
-static void
-setPLL_double_lowregs(struct nv04_clock_priv *priv, u32 NMNMreg,
- struct nouveau_pll_vals *pv)
-{
- /* When setting PLLs, there is a merry game of disabling and enabling
- * various bits of hardware during the process. This function is a
- * synthesis of six nv4x traces, nearly each card doing a subtly
- * different thing. With luck all the necessary bits for each card are
- * combined herein. Without luck it deviates from each card's formula
- * so as to not work on any :)
- */
-
- uint32_t Preg = NMNMreg - 4;
- bool mpll = Preg == 0x4020;
- uint32_t oldPval = nv_rd32(priv, Preg);
- uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
- uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
- 0xc << 28 | pv->log2P << 16;
- uint32_t saved4600 = 0;
- /* some cards have different maskc040s */
- uint32_t maskc040 = ~(3 << 14), savedc040;
- bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
-
- if (nv_rd32(priv, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
- return;
-
- if (Preg == 0x4000)
- maskc040 = ~0x333;
- if (Preg == 0x4058)
- maskc040 = ~(0xc << 24);
-
- if (mpll) {
- struct nvbios_pll info;
- uint8_t Pval2;
-
- if (nvbios_pll_parse(nouveau_bios(priv), Preg, &info))
- return;
-
- Pval2 = pv->log2P + info.bias_p;
- if (Pval2 > info.max_p)
- Pval2 = info.max_p;
- Pval |= 1 << 28 | Pval2 << 20;
-
- saved4600 = nv_rd32(priv, 0x4600);
- nv_wr32(priv, 0x4600, saved4600 | 8 << 28);
- }
- if (single_stage)
- Pval |= mpll ? 1 << 12 : 1 << 8;
-
- nv_wr32(priv, Preg, oldPval | 1 << 28);
- nv_wr32(priv, Preg, Pval & ~(4 << 28));
- if (mpll) {
- Pval |= 8 << 20;
- nv_wr32(priv, 0x4020, Pval & ~(0xc << 28));
- nv_wr32(priv, 0x4038, Pval & ~(0xc << 28));
- }
-
- savedc040 = nv_rd32(priv, 0xc040);
- nv_wr32(priv, 0xc040, savedc040 & maskc040);
-
- nv_wr32(priv, NMNMreg, NMNM);
- if (NMNMreg == 0x4024)
- nv_wr32(priv, 0x403c, NMNM);
-
- nv_wr32(priv, Preg, Pval);
- if (mpll) {
- Pval &= ~(8 << 20);
- nv_wr32(priv, 0x4020, Pval);
- nv_wr32(priv, 0x4038, Pval);
- nv_wr32(priv, 0x4600, saved4600);
- }
-
- nv_wr32(priv, 0xc040, savedc040);
-
- if (mpll) {
- nv_wr32(priv, 0x4020, Pval & ~(1 << 28));
- nv_wr32(priv, 0x4038, Pval & ~(1 << 28));
- }
-}
-
-int
-nv04_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
- struct nv04_clock_priv *priv = (void *)clk;
- struct nouveau_pll_vals pv;
- struct nvbios_pll info;
- int ret;
-
- ret = nvbios_pll_parse(nouveau_bios(priv), type > 0x405c ?
- type : type - 4, &info);
- if (ret)
- return ret;
-
- ret = clk->pll_calc(clk, &info, freq, &pv);
- if (!ret)
- return ret;
-
- return clk->pll_prog(clk, type, &pv);
-}
-
int
nv04_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
int clk, struct nouveau_pll_vals *pv)
{
int N1, M1, N2, M2, P;
- int ret = nv04_pll_calc(clock, info, clk, &N1, &M1, &N2, &M2, &P);
+ int ret = nv04_pll_calc(nv_subdev(clock), info, clk, &N1, &M1, &N2, &M2, &P);
if (ret) {
pv->refclk = info->refclk;
pv->N1 = N1;
@@ -313,17 +54,17 @@ int
nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1,
struct nouveau_pll_vals *pv)
{
- struct nv04_clock_priv *priv = (void *)clk;
+ struct nouveau_devinit *devinit = nouveau_devinit(clk);
int cv = nouveau_bios(clk)->version.chip;
if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
cv >= 0x40) {
if (reg1 > 0x405c)
- setPLL_double_highregs(priv, reg1, pv);
+ setPLL_double_highregs(devinit, reg1, pv);
else
- setPLL_double_lowregs(priv, reg1, pv);
+ setPLL_double_lowregs(devinit, reg1, pv);
} else
- setPLL_single(priv, reg1, pv);
+ setPLL_single(devinit, reg1, pv);
return 0;
}
@@ -341,7 +82,6 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- priv->base.pll_set = nv04_clock_pll_set;
priv->base.pll_calc = nv04_clock_pll_calc;
priv->base.pll_prog = nv04_clock_pll_prog;
return 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
index a4b2b7ebf9af..0db5dbfd91b5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
@@ -41,7 +41,6 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- priv->base.pll_set = nv04_clock_pll_set;
priv->base.pll_calc = nv04_clock_pll_calc;
priv->base.pll_prog = nv04_clock_pll_prog;
return 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
index f4147f67eda6..d09d3e78040c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
@@ -33,50 +33,6 @@ struct nv50_clock_priv {
};
static int
-nv50_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
- struct nv50_clock_priv *priv = (void *)clk;
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll info;
- int N1, M1, N2, M2, P;
- int ret;
-
- ret = nvbios_pll_parse(bios, type, &info);
- if (ret) {
- nv_error(clk, "failed to retrieve pll data, %d\n", ret);
- return ret;
- }
-
- ret = nv04_pll_calc(clk, &info, freq, &N1, &M1, &N2, &M2, &P);
- if (!ret) {
- nv_error(clk, "failed pll calculation\n");
- return ret;
- }
-
- switch (info.type) {
- case PLL_VPLL0:
- case PLL_VPLL1:
- nv_wr32(priv, info.reg + 0, 0x10000611);
- nv_mask(priv, info.reg + 4, 0x00ff00ff, (M1 << 16) | N1);
- nv_mask(priv, info.reg + 8, 0x7fff00ff, (P << 28) |
- (M2 << 16) | N2);
- break;
- case PLL_MEMORY:
- nv_mask(priv, info.reg + 0, 0x01ff0000, (P << 22) |
- (info.bias_p << 19) |
- (P << 16));
- nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
- break;
- default:
- nv_mask(priv, info.reg + 0, 0x00070000, (P << 16));
- nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
- break;
- }
-
- return 0;
-}
-
-static int
nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -89,7 +45,6 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- priv->base.pll_set = nv50_clock_pll_set;
priv->base.pll_calc = nv04_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index 9068c98b96f6..f074cd20bc9c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -32,47 +32,13 @@ struct nva3_clock_priv {
struct nouveau_clock base;
};
-static int
-nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
- struct nva3_clock_priv *priv = (void *)clk;
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll info;
- int N, fN, M, P;
- int ret;
-
- ret = nvbios_pll_parse(bios, type, &info);
- if (ret)
- return ret;
-
- ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
- if (ret < 0)
- return ret;
-
- switch (info.type) {
- case PLL_VPLL0:
- case PLL_VPLL1:
- nv_wr32(priv, info.reg + 0, 0x50000610);
- nv_mask(priv, info.reg + 4, 0x003fffff,
- (P << 16) | (M << 8) | N);
- nv_wr32(priv, info.reg + 8, fN);
- break;
- default:
- nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
int
nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
int clk, struct nouveau_pll_vals *pv)
{
int ret, N, M, P;
- ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P);
+ ret = nva3_pll_calc(nv_subdev(clock), info, clk, &N, NULL, &M, &P);
if (ret > 0) {
pv->refclk = info->refclk;
@@ -97,7 +63,6 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- priv->base.pll_set = nva3_clock_pll_set;
priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
index 7c9626258a46..439d81c26130 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -33,41 +33,6 @@ struct nvc0_clock_priv {
};
static int
-nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
- struct nvc0_clock_priv *priv = (void *)clk;
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll info;
- int N, fN, M, P;
- int ret;
-
- ret = nvbios_pll_parse(bios, type, &info);
- if (ret)
- return ret;
-
- ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
- if (ret < 0)
- return ret;
-
- switch (info.type) {
- case PLL_VPLL0:
- case PLL_VPLL1:
- case PLL_VPLL2:
- case PLL_VPLL3:
- nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
- nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
- nv_wr32(priv, info.reg + 0x10, fN << 16);
- break;
- default:
- nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int
nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -80,7 +45,6 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- priv->base.pll_set = nvc0_clock_pll_set;
priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h b/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
index ef2c0078f337..445b14c33a98 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
@@ -1,9 +1,9 @@
#ifndef __NOUVEAU_PLL_H__
#define __NOUVEAU_PLL_H__
-int nv04_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
+int nv04_pll_calc(struct nouveau_subdev *, struct nvbios_pll *, u32 freq,
int *N1, int *M1, int *N2, int *M2, int *P);
-int nva3_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
+int nva3_pll_calc(struct nouveau_subdev *, struct nvbios_pll *, u32 freq,
int *N, int *fN, int *M, int *P);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
index a2ab6d051ba8..cf1ed0dc9bc9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
@@ -21,14 +21,13 @@
* SOFTWARE.
*/
-#include <subdev/clock.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
#include "pll.h"
static int
-getMNP_single(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
+getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
int *pN, int *pM, int *pP)
{
/* Find M, N and P for a single stage PLL
@@ -39,7 +38,7 @@ getMNP_single(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
* "clk" parameter in kHz
* returns calculated clock
*/
- int cv = nouveau_bios(clock)->version.chip;
+ int cv = nouveau_bios(subdev)->version.chip;
int minvco = info->vco1.min_freq, maxvco = info->vco1.max_freq;
int minM = info->vco1.min_m, maxM = info->vco1.max_m;
int minN = info->vco1.min_n, maxN = info->vco1.max_n;
@@ -124,7 +123,7 @@ getMNP_single(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
}
static int
-getMNP_double(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
+getMNP_double(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
int *pN1, int *pM1, int *pN2, int *pM2, int *pP)
{
/* Find M, N and P for a two stage PLL
@@ -135,7 +134,7 @@ getMNP_double(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
* "clk" parameter in kHz
* returns calculated clock
*/
- int chip_version = nouveau_bios(clock)->version.chip;
+ int chip_version = nouveau_bios(subdev)->version.chip;
int minvco1 = info->vco1.min_freq, maxvco1 = info->vco1.max_freq;
int minvco2 = info->vco2.min_freq, maxvco2 = info->vco2.max_freq;
int minU1 = info->vco1.min_inputfreq, minU2 = info->vco2.min_inputfreq;
@@ -223,20 +222,20 @@ getMNP_double(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
}
int
-nv04_pll_calc(struct nouveau_clock *clk, struct nvbios_pll *info, u32 freq,
+nv04_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info, u32 freq,
int *N1, int *M1, int *N2, int *M2, int *P)
{
int ret;
if (!info->vco2.max_freq) {
- ret = getMNP_single(clk, info, freq, N1, M1, P);
+ ret = getMNP_single(subdev, info, freq, N1, M1, P);
*N2 = 1;
*M2 = 1;
} else {
- ret = getMNP_double(clk, info, freq, N1, M1, N2, M2, P);
+ ret = getMNP_double(subdev, info, freq, N1, M1, N2, M2, P);
}
if (!ret)
- nv_error(clk, "unable to compute acceptable pll values\n");
+ nv_error(subdev, "unable to compute acceptable pll values\n");
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
index eed5c16cf610..2fe1f712eefa 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
@@ -29,7 +29,7 @@
#include "pll.h"
int
-nva3_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
u32 freq, int *pN, int *pfN, int *pM, int *P)
{
u32 best_err = ~0, err;
@@ -50,8 +50,15 @@ nva3_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
u32 tmp = freq * *P * M;
N = tmp / info->refclk;
fN = tmp % info->refclk;
- if (!pfN && fN >= info->refclk / 2)
- N++;
+
+ if (!pfN) {
+ if (fN >= info->refclk / 2)
+ N++;
+ } else {
+ if (fN < info->refclk / 2)
+ N--;
+ fN = tmp - (N * info->refclk);
+ }
if (N < info->vco1.min_n)
continue;
@@ -66,13 +73,14 @@ nva3_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
}
if (pfN) {
- *pfN = (((fN << 13) / info->refclk) - 4096) & 0xffff;
+ *pfN = ((fN << 13) + info->refclk / 2) / info->refclk;
+ *pfN = (*pfN - 4096) & 0xffff;
return freq;
}
}
if (unlikely(best_err == ~0)) {
- nv_error(clock, "unable to find matching pll values\n");
+ nv_error(subdev, "unable to find matching pll values\n");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
index 5a07a39c1735..79c81d3d9bac 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
@@ -29,18 +29,10 @@
#include <subdev/bios/init.h>
int
-nouveau_devinit_init(struct nouveau_devinit *devinit)
+_nouveau_devinit_fini(struct nouveau_object *object, bool suspend)
{
- int ret = nouveau_subdev_init(&devinit->base);
- if (ret)
- return ret;
+ struct nouveau_devinit *devinit = (void *)object;
- return nvbios_init(&devinit->base, devinit->post);
-}
-
-int
-nouveau_devinit_fini(struct nouveau_devinit *devinit, bool suspend)
-{
/* force full reinit on resume */
if (suspend)
devinit->post = true;
@@ -49,6 +41,17 @@ nouveau_devinit_fini(struct nouveau_devinit *devinit, bool suspend)
}
int
+_nouveau_devinit_init(struct nouveau_object *object)
+{
+ struct nouveau_devinit *devinit = (void *)object;
+ int ret = nouveau_subdev_init(&devinit->base);
+ if (ret)
+ return ret;
+
+ return nvbios_init(&devinit->base, devinit->post);
+}
+
+int
nouveau_devinit_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
index 7a72d9394340..b22357d9b821 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
@@ -24,10 +24,10 @@
*
*/
-#include <subdev/devinit.h>
#include <subdev/vga.h>
#include "fbmem.h"
+#include "priv.h"
struct nv04_devinit_priv {
struct nouveau_devinit base;
@@ -111,33 +111,298 @@ nv04_devinit_meminit(struct nouveau_devinit *devinit)
}
static int
-nv04_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+powerctrl_1_shift(int chip_version, int reg)
{
- struct nv04_devinit_priv *priv;
+ int shift = -4;
+
+ if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
+ return shift;
+
+ switch (reg) {
+ case 0x680520:
+ shift += 4;
+ case 0x680508:
+ shift += 4;
+ case 0x680504:
+ shift += 4;
+ case 0x680500:
+ shift += 4;
+ }
+
+ /*
+ * the shift for vpll regs is only used for nv3x chips with a single
+ * stage pll
+ */
+ if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
+ chip_version == 0x36 || chip_version >= 0x40))
+ shift = -4;
+
+ return shift;
+}
+
+void
+setPLL_single(struct nouveau_devinit *devinit, u32 reg,
+ struct nouveau_pll_vals *pv)
+{
+ int chip_version = nouveau_bios(devinit)->version.chip;
+ uint32_t oldpll = nv_rd32(devinit, reg);
+ int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
+ uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+ uint32_t saved_powerctrl_1 = 0;
+ int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
+
+ if (oldpll == pll)
+ return; /* already set */
+
+ if (shift_powerctrl_1 >= 0) {
+ saved_powerctrl_1 = nv_rd32(devinit, 0x001584);
+ nv_wr32(devinit, 0x001584,
+ (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+ 1 << shift_powerctrl_1);
+ }
+
+ if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
+ /* upclock -- write new post divider first */
+ nv_wr32(devinit, reg, pv->log2P << 16 | (oldpll & 0xffff));
+ else
+ /* downclock -- write new NM first */
+ nv_wr32(devinit, reg, (oldpll & 0xffff0000) | pv->NM1);
+
+ if (chip_version < 0x17 && chip_version != 0x11)
+ /* wait a bit on older chips */
+ msleep(64);
+ nv_rd32(devinit, reg);
+
+ /* then write the other half as well */
+ nv_wr32(devinit, reg, pll);
+
+ if (shift_powerctrl_1 >= 0)
+ nv_wr32(devinit, 0x001584, saved_powerctrl_1);
+}
+
+static uint32_t
+new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
+{
+ bool head_a = (reg1 == 0x680508);
+
+ if (ss) /* single stage pll mode */
+ ramdac580 |= head_a ? 0x00000100 : 0x10000000;
+ else
+ ramdac580 &= head_a ? 0xfffffeff : 0xefffffff;
+
+ return ramdac580;
+}
+
+void
+setPLL_double_highregs(struct nouveau_devinit *devinit, u32 reg1,
+ struct nouveau_pll_vals *pv)
+{
+ int chip_version = nouveau_bios(devinit)->version.chip;
+ bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
+ uint32_t reg2 = reg1 + ((reg1 == 0x680520) ? 0x5c : 0x70);
+ uint32_t oldpll1 = nv_rd32(devinit, reg1);
+ uint32_t oldpll2 = !nv3035 ? nv_rd32(devinit, reg2) : 0;
+ uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+ uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
+ uint32_t oldramdac580 = 0, ramdac580 = 0;
+ bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */
+ uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
+ int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
+
+ /* model specific additions to generic pll1 and pll2 set up above */
+ if (nv3035) {
+ pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
+ (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
+ pll2 = 0;
+ }
+ if (chip_version > 0x40 && reg1 >= 0x680508) { /* !nv40 */
+ oldramdac580 = nv_rd32(devinit, 0x680580);
+ ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
+ if (oldramdac580 != ramdac580)
+ oldpll1 = ~0; /* force mismatch */
+ if (single_stage)
+ /* magic value used by nvidia in single stage mode */
+ pll2 |= 0x011f;
+ }
+ if (chip_version > 0x70)
+ /* magic bits set by the blob (but not the bios) on g71-73 */
+ pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
+
+ if (oldpll1 == pll1 && oldpll2 == pll2)
+ return; /* already set */
+
+ if (shift_powerctrl_1 >= 0) {
+ saved_powerctrl_1 = nv_rd32(devinit, 0x001584);
+ nv_wr32(devinit, 0x001584,
+ (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+ 1 << shift_powerctrl_1);
+ }
+
+ if (chip_version >= 0x40) {
+ int shift_c040 = 14;
+
+ switch (reg1) {
+ case 0x680504:
+ shift_c040 += 2;
+ case 0x680500:
+ shift_c040 += 2;
+ case 0x680520:
+ shift_c040 += 2;
+ case 0x680508:
+ shift_c040 += 2;
+ }
+
+ savedc040 = nv_rd32(devinit, 0xc040);
+ if (shift_c040 != 14)
+ nv_wr32(devinit, 0xc040, savedc040 & ~(3 << shift_c040));
+ }
+
+ if (oldramdac580 != ramdac580)
+ nv_wr32(devinit, 0x680580, ramdac580);
+
+ if (!nv3035)
+ nv_wr32(devinit, reg2, pll2);
+ nv_wr32(devinit, reg1, pll1);
+
+ if (shift_powerctrl_1 >= 0)
+ nv_wr32(devinit, 0x001584, saved_powerctrl_1);
+ if (chip_version >= 0x40)
+ nv_wr32(devinit, 0xc040, savedc040);
+}
+
+void
+setPLL_double_lowregs(struct nouveau_devinit *devinit, u32 NMNMreg,
+ struct nouveau_pll_vals *pv)
+{
+ /* When setting PLLs, there is a merry game of disabling and enabling
+ * various bits of hardware during the process. This function is a
+ * synthesis of six nv4x traces, nearly each card doing a subtly
+ * different thing. With luck all the necessary bits for each card are
+ * combined herein. Without luck it deviates from each card's formula
+ * so as to not work on any :)
+ */
+
+ uint32_t Preg = NMNMreg - 4;
+ bool mpll = Preg == 0x4020;
+ uint32_t oldPval = nv_rd32(devinit, Preg);
+ uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
+ uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
+ 0xc << 28 | pv->log2P << 16;
+ uint32_t saved4600 = 0;
+ /* some cards have different maskc040s */
+ uint32_t maskc040 = ~(3 << 14), savedc040;
+ bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
+
+ if (nv_rd32(devinit, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
+ return;
+
+ if (Preg == 0x4000)
+ maskc040 = ~0x333;
+ if (Preg == 0x4058)
+ maskc040 = ~(0xc << 24);
+
+ if (mpll) {
+ struct nvbios_pll info;
+ uint8_t Pval2;
+
+ if (nvbios_pll_parse(nouveau_bios(devinit), Preg, &info))
+ return;
+
+ Pval2 = pv->log2P + info.bias_p;
+ if (Pval2 > info.max_p)
+ Pval2 = info.max_p;
+ Pval |= 1 << 28 | Pval2 << 20;
+
+ saved4600 = nv_rd32(devinit, 0x4600);
+ nv_wr32(devinit, 0x4600, saved4600 | 8 << 28);
+ }
+ if (single_stage)
+ Pval |= mpll ? 1 << 12 : 1 << 8;
+
+ nv_wr32(devinit, Preg, oldPval | 1 << 28);
+ nv_wr32(devinit, Preg, Pval & ~(4 << 28));
+ if (mpll) {
+ Pval |= 8 << 20;
+ nv_wr32(devinit, 0x4020, Pval & ~(0xc << 28));
+ nv_wr32(devinit, 0x4038, Pval & ~(0xc << 28));
+ }
+
+ savedc040 = nv_rd32(devinit, 0xc040);
+ nv_wr32(devinit, 0xc040, savedc040 & maskc040);
+
+ nv_wr32(devinit, NMNMreg, NMNM);
+ if (NMNMreg == 0x4024)
+ nv_wr32(devinit, 0x403c, NMNM);
+
+ nv_wr32(devinit, Preg, Pval);
+ if (mpll) {
+ Pval &= ~(8 << 20);
+ nv_wr32(devinit, 0x4020, Pval);
+ nv_wr32(devinit, 0x4038, Pval);
+ nv_wr32(devinit, 0x4600, saved4600);
+ }
+
+ nv_wr32(devinit, 0xc040, savedc040);
+
+ if (mpll) {
+ nv_wr32(devinit, 0x4020, Pval & ~(1 << 28));
+ nv_wr32(devinit, 0x4038, Pval & ~(1 << 28));
+ }
+}
+
+int
+nv04_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+{
+ struct nouveau_bios *bios = nouveau_bios(devinit);
+ struct nouveau_pll_vals pv;
+ struct nvbios_pll info;
+ int cv = bios->version.chip;
+ int N1, M1, N2, M2, P;
int ret;
- ret = nouveau_devinit_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
+ ret = nvbios_pll_parse(bios, type > 0x405c ? type : type - 4, &info);
if (ret)
return ret;
- priv->base.meminit = nv04_devinit_meminit;
- priv->owner = -1;
+ ret = nv04_pll_calc(nv_subdev(devinit), &info, freq,
+ &N1, &M1, &N2, &M2, &P);
+ if (!ret)
+ return -EINVAL;
+
+ pv.refclk = info.refclk;
+ pv.N1 = N1;
+ pv.M1 = M1;
+ pv.N2 = N2;
+ pv.M2 = M2;
+ pv.log2P = P;
+
+ if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
+ cv >= 0x40) {
+ if (type > 0x405c)
+ setPLL_double_highregs(devinit, type, &pv);
+ else
+ setPLL_double_lowregs(devinit, type, &pv);
+ } else
+ setPLL_single(devinit, type, &pv);
+
return 0;
}
-void
-nv04_devinit_dtor(struct nouveau_object *object)
+int
+nv04_devinit_fini(struct nouveau_object *object, bool suspend)
{
struct nv04_devinit_priv *priv = (void *)object;
- /* restore vga owner saved at first init, and lock crtc regs */
- nv_wrvgaowner(priv, priv->owner);
- nv_lockvgac(priv, true);
+ /* make i2c busses accessible */
+ nv_mask(priv, 0x000200, 0x00000001, 0x00000001);
- nouveau_devinit_destroy(&priv->base);
+ /* unlock extended vga crtc regs, and unslave crtcs */
+ nv_lockvgac(priv, false);
+ if (priv->owner < 0)
+ priv->owner = nv_rdvgaowner(priv);
+ nv_wrvgaowner(priv, 0);
+
+ return nouveau_devinit_fini(&priv->base, suspend);
}
int
@@ -160,21 +425,35 @@ nv04_devinit_init(struct nouveau_object *object)
return nouveau_devinit_init(&priv->base);
}
-int
-nv04_devinit_fini(struct nouveau_object *object, bool suspend)
+void
+nv04_devinit_dtor(struct nouveau_object *object)
{
struct nv04_devinit_priv *priv = (void *)object;
- /* make i2c busses accessible */
- nv_mask(priv, 0x000200, 0x00000001, 0x00000001);
+ /* restore vga owner saved at first init, and lock crtc regs */
+ nv_wrvgaowner(priv, priv->owner);
+ nv_lockvgac(priv, true);
- /* unlock extended vga crtc regs, and unslave crtcs */
- nv_lockvgac(priv, false);
- if (priv->owner < 0)
- priv->owner = nv_rdvgaowner(priv);
- nv_wrvgaowner(priv, 0);
+ nouveau_devinit_destroy(&priv->base);
+}
- return nouveau_devinit_fini(&priv->base, suspend);
+static int
+nv04_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.meminit = nv04_devinit_meminit;
+ priv->base.pll_set = nv04_devinit_pll_set;
+ priv->owner = -1;
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
index 191447d0d252..b1912a8a8942 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
@@ -24,12 +24,12 @@
*
*/
-#include <subdev/devinit.h>
#include <subdev/bios.h>
#include <subdev/bios/bmp.h>
#include <subdev/vga.h>
#include "fbmem.h"
+#include "priv.h"
struct nv05_devinit_priv {
struct nouveau_devinit base;
@@ -144,6 +144,7 @@ nv05_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
priv->base.meminit = nv05_devinit_meminit;
+ priv->base.pll_set = nv04_devinit_pll_set;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
index eb76ffab6b0c..463b08fa0968 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
@@ -24,10 +24,10 @@
*
*/
-#include <subdev/devinit.h>
#include <subdev/vga.h>
#include "fbmem.h"
+#include "priv.h"
struct nv10_devinit_priv {
struct nouveau_devinit base;
@@ -109,6 +109,7 @@ nv10_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
priv->base.meminit = nv10_devinit_meminit;
+ priv->base.pll_set = nv04_devinit_pll_set;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
index 5b2ba630d913..e9743cdabe75 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
@@ -22,8 +22,7 @@
* Authors: Ben Skeggs
*/
-#include <subdev/devinit.h>
-#include <subdev/vga.h>
+#include "priv.h"
struct nv1a_devinit_priv {
struct nouveau_devinit base;
@@ -43,6 +42,7 @@ nv1a_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
+ priv->base.pll_set = nv04_devinit_pll_set;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
index eb32e99005e4..6cc6080d3bc0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
@@ -24,9 +24,7 @@
*
*/
-#include <subdev/devinit.h>
-#include <subdev/vga.h>
-
+#include "priv.h"
#include "fbmem.h"
struct nv20_devinit_priv {
@@ -81,6 +79,7 @@ nv20_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
priv->base.meminit = nv20_devinit_meminit;
+ priv->base.pll_set = nv04_devinit_pll_set;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
index 4a8577838417..6df72247c477 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Red Hat Inc.
+ * Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,37 +26,55 @@
#include <subdev/bios/dcb.h>
#include <subdev/bios/disp.h>
#include <subdev/bios/init.h>
-#include <subdev/devinit.h>
#include <subdev/vga.h>
-struct nv50_devinit_priv {
- struct nouveau_devinit base;
-};
+#include "priv.h"
static int
-nv50_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
{
- struct nv50_devinit_priv *priv;
+ struct nv50_devinit_priv *priv = (void *)devinit;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvbios_pll info;
+ int N1, M1, N2, M2, P;
int ret;
- ret = nouveau_devinit_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
+ ret = nvbios_pll_parse(bios, type, &info);
+ if (ret) {
+ nv_error(devinit, "failed to retrieve pll data, %d\n", ret);
return ret;
+ }
- return 0;
-}
+ ret = nv04_pll_calc(nv_subdev(devinit), &info, freq, &N1, &M1, &N2, &M2, &P);
+ if (!ret) {
+ nv_error(devinit, "failed pll calculation\n");
+ return ret;
+ }
-static void
-nv50_devinit_dtor(struct nouveau_object *object)
-{
- struct nv50_devinit_priv *priv = (void *)object;
- nouveau_devinit_destroy(&priv->base);
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
+ nv_wr32(priv, info.reg + 0, 0x10000611);
+ nv_mask(priv, info.reg + 4, 0x00ff00ff, (M1 << 16) | N1);
+ nv_mask(priv, info.reg + 8, 0x7fff00ff, (P << 28) |
+ (M2 << 16) | N2);
+ break;
+ case PLL_MEMORY:
+ nv_mask(priv, info.reg + 0, 0x01ff0000, (P << 22) |
+ (info.bias_p << 19) |
+ (P << 16));
+ nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
+ break;
+ default:
+ nv_mask(priv, info.reg + 0, 0x00070000, (P << 16));
+ nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
+ break;
+ }
+
+ return 0;
}
-static int
+int
nv50_devinit_init(struct nouveau_object *object)
{
struct nouveau_bios *bios = nouveau_bios(object);
@@ -103,10 +121,20 @@ nv50_devinit_init(struct nouveau_object *object)
}
static int
-nv50_devinit_fini(struct nouveau_object *object, bool suspend)
+nv50_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
{
- struct nv50_devinit_priv *priv = (void *)object;
- return nouveau_devinit_fini(&priv->base, suspend);
+ struct nv50_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.pll_set = nv50_devinit_pll_set;
+ return 0;
}
struct nouveau_oclass
@@ -114,8 +142,8 @@ nv50_devinit_oclass = {
.handle = NV_SUBDEV(DEVINIT, 0x50),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = nv50_devinit_dtor,
+ .dtor = _nouveau_devinit_dtor,
.init = nv50_devinit_init,
- .fini = nv50_devinit_fini,
+ .fini = _nouveau_devinit_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
new file mode 100644
index 000000000000..76a68b290141
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nva3_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+{
+ struct nva3_devinit_priv *priv = (void *)devinit;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvbios_pll info;
+ int N, fN, M, P;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, type, &info);
+ if (ret)
+ return ret;
+
+ ret = nva3_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
+ if (ret < 0)
+ return ret;
+
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
+ nv_wr32(priv, info.reg + 0, 0x50000610);
+ nv_mask(priv, info.reg + 4, 0x003fffff,
+ (P << 16) | (M << 8) | N);
+ nv_wr32(priv, info.reg + 8, fN);
+ break;
+ default:
+ nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+nva3_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.pll_set = nva3_devinit_pll_set;
+ return 0;
+}
+
+struct nouveau_oclass
+nva3_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0xa3),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nva3_devinit_ctor,
+ .dtor = _nouveau_devinit_dtor,
+ .init = nv50_devinit_init,
+ .fini = _nouveau_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c
new file mode 100644
index 000000000000..af407a8637c7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nvc0_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+{
+ struct nvc0_devinit_priv *priv = (void *)devinit;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvbios_pll info;
+ int N, fN, M, P;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, type, &info);
+ if (ret)
+ return ret;
+
+ ret = nva3_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
+ if (ret < 0)
+ return ret;
+
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
+ case PLL_VPLL2:
+ case PLL_VPLL3:
+ nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
+ nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
+ nv_wr32(priv, info.reg + 0x10, fN << 16);
+ break;
+ default:
+ nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+nvc0_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.pll_set = nvc0_devinit_pll_set;
+ if (nv_rd32(priv, 0x022500) & 0x00000001)
+ priv->base.post = true;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0xa3),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_devinit_ctor,
+ .dtor = _nouveau_devinit_dtor,
+ .init = nv50_devinit_init,
+ .fini = _nouveau_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
new file mode 100644
index 000000000000..7d622e2b0171
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
@@ -0,0 +1,25 @@
+#ifndef __NVKM_DEVINIT_PRIV_H__
+#define __NVKM_DEVINIT_PRIV_H__
+
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+#include <subdev/clock/pll.h>
+#include <subdev/devinit.h>
+
+void nv04_devinit_dtor(struct nouveau_object *);
+int nv04_devinit_init(struct nouveau_object *);
+int nv04_devinit_fini(struct nouveau_object *, bool);
+int nv04_devinit_pll_set(struct nouveau_devinit *, u32, u32);
+
+void setPLL_single(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
+void setPLL_double_highregs(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
+void setPLL_double_lowregs(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
+
+
+struct nv50_devinit_priv {
+ struct nouveau_devinit base;
+};
+
+int nv50_devinit_init(struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
index d62045f454b2..821cd75b86a3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
@@ -57,7 +57,57 @@ nouveau_fb_bios_memtype(struct nouveau_bios *bios)
}
int
-nouveau_fb_preinit(struct nouveau_fb *pfb)
+_nouveau_fb_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nouveau_fb *pfb = (void *)object;
+ int ret;
+
+ ret = nv_ofuncs(pfb->ram)->fini(nv_object(pfb->ram), suspend);
+ if (ret && suspend)
+ return ret;
+
+ return nouveau_subdev_fini(&pfb->base, suspend);
+}
+
+int
+_nouveau_fb_init(struct nouveau_object *object)
+{
+ struct nouveau_fb *pfb = (void *)object;
+ int ret, i;
+
+ ret = nouveau_subdev_init(&pfb->base);
+ if (ret)
+ return ret;
+
+ ret = nv_ofuncs(pfb->ram)->init(nv_object(pfb->ram));
+ if (ret)
+ return ret;
+
+ for (i = 0; i < pfb->tile.regions; i++)
+ pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
+
+ return 0;
+}
+
+void
+_nouveau_fb_dtor(struct nouveau_object *object)
+{
+ struct nouveau_fb *pfb = (void *)object;
+ int i;
+
+ for (i = 0; i < pfb->tile.regions; i++)
+ pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
+ nouveau_mm_fini(&pfb->tags);
+ nouveau_mm_fini(&pfb->vram);
+
+ nouveau_object_ref(NULL, (struct nouveau_object **)&pfb->ram);
+ nouveau_subdev_destroy(&pfb->base);
+}
+
+int
+nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, struct nouveau_oclass *ramcls,
+ int length, void **pobject)
{
static const char *name[] = {
[NV_MEM_TYPE_UNKNOWN] = "unknown",
@@ -72,69 +122,42 @@ nouveau_fb_preinit(struct nouveau_fb *pfb)
[NV_MEM_TYPE_GDDR4 ] = "GDDR4",
[NV_MEM_TYPE_GDDR5 ] = "GDDR5",
};
- int ret, tags;
+ struct nouveau_object *ram;
+ struct nouveau_fb *pfb;
+ int ret;
- tags = pfb->ram.init(pfb);
- if (tags < 0 || !pfb->ram.size) {
+ ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PFB", "fb",
+ length, pobject);
+ pfb = *pobject;
+ if (ret)
+ return ret;
+
+ ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb),
+ ramcls, NULL, 0, &ram);
+ if (ret) {
nv_fatal(pfb, "error detecting memory configuration!!\n");
- return (tags < 0) ? tags : -ERANGE;
+ return ret;
}
+ atomic_dec(&ram->parent->refcount);
+ atomic_dec(&ram->engine->refcount);
+ pfb->ram = (void *)ram;
+
if (!nouveau_mm_initialised(&pfb->vram)) {
- ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram.size >> 12, 1);
+ ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram->size >> 12, 1);
if (ret)
return ret;
}
if (!nouveau_mm_initialised(&pfb->tags)) {
- ret = nouveau_mm_init(&pfb->tags, 0, tags ? ++tags : 0, 1);
+ ret = nouveau_mm_init(&pfb->tags, 0, pfb->ram->tags ?
+ ++pfb->ram->tags : 0, 1);
if (ret)
return ret;
}
- nv_info(pfb, "RAM type: %s\n", name[pfb->ram.type]);
- nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram.size >> 20));
- nv_info(pfb, " ZCOMP: %d tags\n", tags);
+ nv_info(pfb, "RAM type: %s\n", name[pfb->ram->type]);
+ nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram->size >> 20));
+ nv_info(pfb, " ZCOMP: %d tags\n", pfb->ram->tags);
return 0;
}
-
-void
-nouveau_fb_destroy(struct nouveau_fb *pfb)
-{
- int i;
-
- for (i = 0; i < pfb->tile.regions; i++)
- pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
- nouveau_mm_fini(&pfb->tags);
- nouveau_mm_fini(&pfb->vram);
-
- nouveau_subdev_destroy(&pfb->base);
-}
-
-void
-_nouveau_fb_dtor(struct nouveau_object *object)
-{
- struct nouveau_fb *pfb = (void *)object;
- nouveau_fb_destroy(pfb);
-}
-int
-nouveau_fb_init(struct nouveau_fb *pfb)
-{
- int ret, i;
-
- ret = nouveau_subdev_init(&pfb->base);
- if (ret)
- return ret;
-
- for (i = 0; i < pfb->tile.regions; i++)
- pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
-
- return 0;
-}
-
-int
-_nouveau_fb_init(struct nouveau_object *object)
-{
- struct nouveau_fb *pfb = (void *)object;
- return nouveau_fb_init(pfb);
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
index 6e369f85361e..1f103c7b89fa 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
@@ -22,24 +22,8 @@
* Authors: Ben Skeggs
*/
-#include <subdev/fb.h>
+#include "priv.h"
-#define NV04_PFB_BOOT_0 0x00100000
-# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
-# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000
-# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001
-# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002
-# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003
-# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004
-# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028
-# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000
-# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008
-# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010
-# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018
-# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020
-# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
-# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
-# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
#define NV04_PFB_CFG0 0x00100200
struct nv04_fb_priv {
@@ -56,37 +40,6 @@ nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
}
static int
-nv04_fb_vram_init(struct nouveau_fb *pfb)
-{
- u32 boot0 = nv_rd32(pfb, NV04_PFB_BOOT_0);
- if (boot0 & 0x00000100) {
- pfb->ram.size = ((boot0 >> 12) & 0xf) * 2 + 2;
- pfb->ram.size *= 1024 * 1024;
- } else {
- switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
- case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
- pfb->ram.size = 32 * 1024 * 1024;
- break;
- case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
- pfb->ram.size = 16 * 1024 * 1024;
- break;
- case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
- pfb->ram.size = 8 * 1024 * 1024;
- break;
- case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
- pfb->ram.size = 4 * 1024 * 1024;
- break;
- }
- }
-
- if ((boot0 & 0x00000038) <= 0x10)
- pfb->ram.type = NV_MEM_TYPE_SGRAM;
- else
- pfb->ram.type = NV_MEM_TYPE_SDRAM;
- return 0;
-}
-
-static int
nv04_fb_init(struct nouveau_object *object)
{
struct nv04_fb_priv *priv = (void *)object;
@@ -112,14 +65,13 @@ nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv04_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv04_fb_vram_init;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
index edbbe26e858d..be069b5306b6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
@@ -24,25 +24,12 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv10_fb_priv {
struct nouveau_fb base;
};
-static int
-nv10_fb_vram_init(struct nouveau_fb *pfb)
-{
- u32 cfg0 = nv_rd32(pfb, 0x100200);
- if (cfg0 & 0x00000001)
- pfb->ram.type = NV_MEM_TYPE_DDR1;
- else
- pfb->ram.type = NV_MEM_TYPE_SDRAM;
-
- pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- return 0;
-}
-
void
nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
u32 flags, struct nouveau_fb_tile *tile)
@@ -78,18 +65,17 @@ nv10_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv10_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv10_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv10_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv10_fb_tile_init;
priv->base.tile.fini = nv10_fb_tile_fini;
priv->base.tile.prog = nv10_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
index 48366841db4a..57a2af0079b3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
@@ -24,38 +24,13 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv1a_fb_priv {
struct nouveau_fb base;
};
static int
-nv1a_fb_vram_init(struct nouveau_fb *pfb)
-{
- struct pci_dev *bridge;
- u32 mem, mib;
-
- bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
- if (!bridge) {
- nv_fatal(pfb, "no bridge device\n");
- return -ENODEV;
- }
-
- if (nv_device(pfb)->chipset == 0x1a) {
- pci_read_config_dword(bridge, 0x7c, &mem);
- mib = ((mem >> 6) & 31) + 1;
- } else {
- pci_read_config_dword(bridge, 0x84, &mem);
- mib = ((mem >> 4) & 127) + 1;
- }
-
- pfb->ram.type = NV_MEM_TYPE_STOLEN;
- pfb->ram.size = mib * 1024 * 1024;
- return 0;
-}
-
-static int
nv1a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -63,18 +38,17 @@ nv1a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv1a_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv1a_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv1a_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv10_fb_tile_init;
priv->base.tile.fini = nv10_fb_tile_fini;
priv->base.tile.prog = nv10_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
index 5d14612a2c8e..b18c4e63bb47 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
@@ -24,29 +24,12 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv20_fb_priv {
struct nouveau_fb base;
};
-int
-nv20_fb_vram_init(struct nouveau_fb *pfb)
-{
- u32 pbus1218 = nv_rd32(pfb, 0x001218);
-
- switch (pbus1218 & 0x00000300) {
- case 0x00000000: pfb->ram.type = NV_MEM_TYPE_SDRAM; break;
- case 0x00000100: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
- case 0x00000200: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
- case 0x00000300: pfb->ram.type = NV_MEM_TYPE_GDDR2; break;
- }
- pfb->ram.size = (nv_rd32(pfb, 0x10020c) & 0xff000000);
- pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
-
- return nv_rd32(pfb, 0x100320);
-}
-
void
nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
u32 flags, struct nouveau_fb_tile *tile)
@@ -65,7 +48,7 @@ nv20_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
struct nouveau_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
- u32 tags = round_up(tiles / pfb->ram.parts, 0x40);
+ u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
if (!(flags & 2)) tile->zcomp = 0x00000000; /* Z16 */
else tile->zcomp = 0x04000000; /* Z24S8 */
@@ -105,19 +88,18 @@ nv20_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv20_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv20_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv20_fb_tile_init;
priv->base.tile.comp = nv20_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv20_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
index 0042ace6bef9..32ccabf10c45 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
@@ -24,7 +24,7 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv25_fb_priv {
struct nouveau_fb base;
@@ -35,7 +35,7 @@ nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
struct nouveau_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
- u32 tags = round_up(tiles / pfb->ram.parts, 0x40);
+ u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
if (!(flags & 2)) tile->zcomp = 0x00100000; /* Z16 */
else tile->zcomp = 0x00200000; /* Z24S8 */
@@ -54,19 +54,18 @@ nv25_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv25_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv20_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv20_fb_tile_init;
priv->base.tile.comp = nv25_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv20_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
index a7ba0d048aec..bef756d43d33 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
@@ -24,7 +24,7 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv30_fb_priv {
struct nouveau_fb base;
@@ -54,7 +54,7 @@ nv30_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
struct nouveau_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
- u32 tags = round_up(tiles / pfb->ram.parts, 0x40);
+ u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x01000000; /* Z16 */
else tile->zcomp |= 0x02000000; /* Z24S8 */
@@ -132,19 +132,18 @@ nv30_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv30_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv20_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv30_fb_tile_init;
priv->base.tile.comp = nv30_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv20_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
index 092f6f4f3521..097d8e3824f2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
@@ -24,7 +24,7 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv35_fb_priv {
struct nouveau_fb base;
@@ -35,7 +35,7 @@ nv35_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
struct nouveau_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
- u32 tags = round_up(tiles / pfb->ram.parts, 0x40);
+ u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x04000000; /* Z16 */
else tile->zcomp |= 0x08000000; /* Z24S8 */
@@ -55,19 +55,18 @@ nv35_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv35_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv20_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv30_fb_tile_init;
priv->base.tile.comp = nv35_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv20_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
index 797ab3b821b9..9d6d9df896d9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
@@ -24,7 +24,7 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv36_fb_priv {
struct nouveau_fb base;
@@ -35,7 +35,7 @@ nv36_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
struct nouveau_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
- u32 tags = round_up(tiles / pfb->ram.parts, 0x40);
+ u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x10000000; /* Z16 */
else tile->zcomp |= 0x20000000; /* Z24S8 */
@@ -55,19 +55,18 @@ nv36_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv36_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv20_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv30_fb_tile_init;
priv->base.tile.comp = nv36_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv20_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
index 65e131b90f37..33b4393a7829 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
@@ -24,34 +24,18 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv40_fb_priv {
struct nouveau_fb base;
};
-static int
-nv40_fb_vram_init(struct nouveau_fb *pfb)
-{
- u32 pbus1218 = nv_rd32(pfb, 0x001218);
- switch (pbus1218 & 0x00000300) {
- case 0x00000000: pfb->ram.type = NV_MEM_TYPE_SDRAM; break;
- case 0x00000100: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
- case 0x00000200: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
- case 0x00000300: pfb->ram.type = NV_MEM_TYPE_DDR2; break;
- }
-
- pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
- return nv_rd32(pfb, 0x100320);
-}
-
void
nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
struct nouveau_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x80);
- u32 tags = round_up(tiles / pfb->ram.parts, 0x100);
+ u32 tags = round_up(tiles / pfb->ram->parts, 0x100);
if ( (flags & 2) &&
!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
tile->zcomp = 0x28000000; /* Z24S8_SPLIT_GRAD */
@@ -85,19 +69,18 @@ nv40_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv40_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv40_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv40_fb_vram_init;
priv->base.tile.regions = 8;
priv->base.tile.init = nv30_fb_tile_init;
priv->base.tile.comp = nv40_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv20_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
index e9e5a08c41a1..02cd83789cd4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
@@ -24,28 +24,12 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv41_fb_priv {
struct nouveau_fb base;
};
-int
-nv41_fb_vram_init(struct nouveau_fb *pfb)
-{
- u32 pfb474 = nv_rd32(pfb, 0x100474);
- if (pfb474 & 0x00000004)
- pfb->ram.type = NV_MEM_TYPE_GDDR3;
- if (pfb474 & 0x00000002)
- pfb->ram.type = NV_MEM_TYPE_DDR2;
- if (pfb474 & 0x00000001)
- pfb->ram.type = NV_MEM_TYPE_DDR1;
-
- pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
- return nv_rd32(pfb, 0x100320);
-}
-
void
nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
{
@@ -78,19 +62,18 @@ nv41_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv41_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv41_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv41_fb_vram_init;
priv->base.tile.regions = 12;
priv->base.tile.init = nv30_fb_tile_init;
priv->base.tile.comp = nv40_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv41_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
index ae89b5006f7a..c5246c29f293 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
@@ -24,27 +24,12 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv44_fb_priv {
struct nouveau_fb base;
};
-int
-nv44_fb_vram_init(struct nouveau_fb *pfb)
-{
- u32 pfb474 = nv_rd32(pfb, 0x100474);
- if (pfb474 & 0x00000004)
- pfb->ram.type = NV_MEM_TYPE_GDDR3;
- if (pfb474 & 0x00000002)
- pfb->ram.type = NV_MEM_TYPE_DDR2;
- if (pfb474 & 0x00000001)
- pfb->ram.type = NV_MEM_TYPE_DDR1;
-
- pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- return 0;
-}
-
static void
nv44_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
u32 flags, struct nouveau_fb_tile *tile)
@@ -87,18 +72,17 @@ nv44_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv44_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv44_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv44_fb_vram_init;
priv->base.tile.regions = 12;
priv->base.tile.init = nv44_fb_tile_init;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv44_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
index 589b93ea2994..e2b57909bfca 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
@@ -24,7 +24,7 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv46_fb_priv {
struct nouveau_fb base;
@@ -52,18 +52,17 @@ nv46_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv46_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv44_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv44_fb_vram_init;
priv->base.tile.regions = 15;
priv->base.tile.init = nv46_fb_tile_init;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv44_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
index 818bba35b368..fe6a2278621d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
@@ -24,7 +24,7 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv47_fb_priv {
struct nouveau_fb base;
@@ -38,19 +38,18 @@ nv47_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv47_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv41_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv41_fb_vram_init;
priv->base.tile.regions = 15;
priv->base.tile.init = nv30_fb_tile_init;
priv->base.tile.comp = nv40_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv41_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
index 84a31af16ab4..5eca99b8c7e2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
@@ -24,30 +24,13 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv49_fb_priv {
struct nouveau_fb base;
};
static int
-nv49_fb_vram_init(struct nouveau_fb *pfb)
-{
- u32 pfb914 = nv_rd32(pfb, 0x100914);
-
- switch (pfb914 & 0x00000003) {
- case 0x00000000: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
- case 0x00000001: pfb->ram.type = NV_MEM_TYPE_DDR2; break;
- case 0x00000002: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
- case 0x00000003: break;
- }
-
- pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
- return nv_rd32(pfb, 0x100320);
-}
-
-static int
nv49_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -55,20 +38,18 @@ nv49_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv49_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv49_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv49_fb_vram_init;
priv->base.tile.regions = 15;
priv->base.tile.init = nv30_fb_tile_init;
priv->base.tile.comp = nv40_fb_tile_comp;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv41_fb_tile_prog;
-
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
index 797fd558170b..1190b78a1e91 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
@@ -24,21 +24,13 @@
*
*/
-#include <subdev/fb.h>
+#include "priv.h"
struct nv4e_fb_priv {
struct nouveau_fb base;
};
static int
-nv4e_fb_vram_init(struct nouveau_fb *pfb)
-{
- pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- pfb->ram.type = NV_MEM_TYPE_STOLEN;
- return 0;
-}
-
-static int
nv4e_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -46,18 +38,17 @@ nv4e_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv4e_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv4e_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nv04_fb_memtype_valid;
- priv->base.ram.init = nv4e_fb_vram_init;
priv->base.tile.regions = 12;
priv->base.tile.init = nv46_fb_tile_init;
priv->base.tile.fini = nv20_fb_tile_fini;
priv->base.tile.prog = nv44_fb_tile_prog;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
index 0772ec978165..da614ec5564b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
@@ -27,7 +27,7 @@
#include <core/engctx.h>
#include <core/object.h>
-#include <subdev/fb.h>
+#include "priv.h"
#include <subdev/bios.h>
struct nv50_fb_priv {
@@ -36,7 +36,8 @@ struct nv50_fb_priv {
dma_addr_t r100c08;
};
-static int types[0x80] = {
+int
+nv50_fb_memtype[0x80] = {
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
@@ -50,192 +51,7 @@ static int types[0x80] = {
static bool
nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype)
{
- return types[(memtype & 0xff00) >> 8] != 0;
-}
-
-static u32
-nv50_fb_vram_rblock(struct nouveau_fb *pfb)
-{
- int i, parts, colbits, rowbitsa, rowbitsb, banks;
- u64 rowsize, predicted;
- u32 r0, r4, rt, ru, rblock_size;
-
- r0 = nv_rd32(pfb, 0x100200);
- r4 = nv_rd32(pfb, 0x100204);
- rt = nv_rd32(pfb, 0x100250);
- ru = nv_rd32(pfb, 0x001540);
- nv_debug(pfb, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
-
- for (i = 0, parts = 0; i < 8; i++) {
- if (ru & (0x00010000 << i))
- parts++;
- }
-
- colbits = (r4 & 0x0000f000) >> 12;
- rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
- rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
- banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
-
- rowsize = parts * banks * (1 << colbits) * 8;
- predicted = rowsize << rowbitsa;
- if (r0 & 0x00000004)
- predicted += rowsize << rowbitsb;
-
- if (predicted != pfb->ram.size) {
- nv_warn(pfb, "memory controller reports %d MiB VRAM\n",
- (u32)(pfb->ram.size >> 20));
- }
-
- rblock_size = rowsize;
- if (rt & 1)
- rblock_size *= 3;
-
- nv_debug(pfb, "rblock %d bytes\n", rblock_size);
- return rblock_size;
-}
-
-static int
-nv50_fb_vram_init(struct nouveau_fb *pfb)
-{
- struct nouveau_device *device = nv_device(pfb);
- struct nouveau_bios *bios = nouveau_bios(device);
- const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
- const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
- u32 size, tags = 0;
- int ret;
-
- pfb->ram.size = nv_rd32(pfb, 0x10020c);
- pfb->ram.size = (pfb->ram.size & 0xffffff00) |
- ((pfb->ram.size & 0x000000ff) << 32);
-
- size = (pfb->ram.size >> 12) - rsvd_head - rsvd_tail;
- switch (device->chipset) {
- case 0xaa:
- case 0xac:
- case 0xaf: /* IGPs, no reordering, no real VRAM */
- ret = nouveau_mm_init(&pfb->vram, rsvd_head, size, 1);
- if (ret)
- return ret;
-
- pfb->ram.type = NV_MEM_TYPE_STOLEN;
- pfb->ram.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
- break;
- default:
- switch (nv_rd32(pfb, 0x100714) & 0x00000007) {
- case 0: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
- case 1:
- if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
- pfb->ram.type = NV_MEM_TYPE_DDR3;
- else
- pfb->ram.type = NV_MEM_TYPE_DDR2;
- break;
- case 2: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
- case 3: pfb->ram.type = NV_MEM_TYPE_GDDR4; break;
- case 4: pfb->ram.type = NV_MEM_TYPE_GDDR5; break;
- default:
- break;
- }
-
- ret = nouveau_mm_init(&pfb->vram, rsvd_head, size,
- nv50_fb_vram_rblock(pfb) >> 12);
- if (ret)
- return ret;
-
- pfb->ram.ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1;
- tags = nv_rd32(pfb, 0x100320);
- break;
- }
-
- return tags;
-}
-
-static int
-nv50_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **pmem)
-{
- struct nv50_fb_priv *priv = (void *)pfb;
- struct nouveau_mm *heap = &priv->base.vram;
- struct nouveau_mm *tags = &priv->base.tags;
- struct nouveau_mm_node *r;
- struct nouveau_mem *mem;
- int comp = (memtype & 0x300) >> 8;
- int type = (memtype & 0x07f);
- int back = (memtype & 0x800);
- int min, max, ret;
-
- max = (size >> 12);
- min = ncmin ? (ncmin >> 12) : max;
- align >>= 12;
-
- mem = kzalloc(sizeof(*mem), GFP_KERNEL);
- if (!mem)
- return -ENOMEM;
-
- mutex_lock(&pfb->base.mutex);
- if (comp) {
- if (align == 16) {
- int n = (max >> 4) * comp;
-
- ret = nouveau_mm_head(tags, 1, n, n, 1, &mem->tag);
- if (ret)
- mem->tag = NULL;
- }
-
- if (unlikely(!mem->tag))
- comp = 0;
- }
-
- INIT_LIST_HEAD(&mem->regions);
- mem->memtype = (comp << 7) | type;
- mem->size = max;
-
- type = types[type];
- do {
- if (back)
- ret = nouveau_mm_tail(heap, type, max, min, align, &r);
- else
- ret = nouveau_mm_head(heap, type, max, min, align, &r);
- if (ret) {
- mutex_unlock(&pfb->base.mutex);
- pfb->ram.put(pfb, &mem);
- return ret;
- }
-
- list_add_tail(&r->rl_entry, &mem->regions);
- max -= r->length;
- } while (max);
- mutex_unlock(&pfb->base.mutex);
-
- r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
- mem->offset = (u64)r->offset << 12;
- *pmem = mem;
- return 0;
-}
-
-void
-nv50_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
-{
- struct nv50_fb_priv *priv = (void *)pfb;
- struct nouveau_mm_node *this;
- struct nouveau_mem *mem;
-
- mem = *pmem;
- *pmem = NULL;
- if (unlikely(mem == NULL))
- return;
-
- mutex_lock(&pfb->base.mutex);
- while (!list_empty(&mem->regions)) {
- this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
-
- list_del(&this->rl_entry);
- nouveau_mm_free(&priv->base.vram, &this);
- }
-
- nouveau_mm_free(&priv->base.tags, &mem->tag);
- mutex_unlock(&pfb->base.mutex);
-
- kfree(mem);
+ return nv50_fb_memtype[(memtype & 0xff00) >> 8] != 0;
}
static const struct nouveau_enum vm_dispatch_subclients[] = {
@@ -432,7 +248,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv50_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nv50_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -449,11 +265,8 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
priv->base.memtype_valid = nv50_fb_memtype_valid;
- priv->base.ram.init = nv50_fb_vram_init;
- priv->base.ram.get = nv50_fb_vram_new;
- priv->base.ram.put = nv50_fb_vram_del;
nv_subdev(priv)->intr = nv50_fb_intr;
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
static void
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index 86ad59203c8b..f35d76fd746d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -22,9 +22,7 @@
* Authors: Ben Skeggs
*/
-#include <subdev/fb.h>
-#include <subdev/ltcg.h>
-#include <subdev/bios.h>
+#include "priv.h"
struct nvc0_fb_priv {
struct nouveau_fb base;
@@ -34,7 +32,6 @@ struct nvc0_fb_priv {
extern const u8 nvc0_pte_storage_type_map[256];
-
static bool
nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
{
@@ -43,137 +40,6 @@ nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
}
static int
-nvc0_fb_vram_init(struct nouveau_fb *pfb)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
- const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
- u32 parts = nv_rd32(pfb, 0x022438);
- u32 pmask = nv_rd32(pfb, 0x022554);
- u32 bsize = nv_rd32(pfb, 0x10f20c);
- u32 offset, length;
- bool uniform = true;
- int ret, part;
-
- nv_debug(pfb, "0x100800: 0x%08x\n", nv_rd32(pfb, 0x100800));
- nv_debug(pfb, "parts 0x%08x mask 0x%08x\n", parts, pmask);
-
- pfb->ram.type = nouveau_fb_bios_memtype(bios);
- pfb->ram.ranks = (nv_rd32(pfb, 0x10f200) & 0x00000004) ? 2 : 1;
-
- /* read amount of vram attached to each memory controller */
- for (part = 0; part < parts; part++) {
- if (!(pmask & (1 << part))) {
- u32 psize = nv_rd32(pfb, 0x11020c + (part * 0x1000));
- if (psize != bsize) {
- if (psize < bsize)
- bsize = psize;
- uniform = false;
- }
-
- nv_debug(pfb, "%d: mem_amount 0x%08x\n", part, psize);
- pfb->ram.size += (u64)psize << 20;
- }
- }
-
- /* if all controllers have the same amount attached, there's no holes */
- if (uniform) {
- offset = rsvd_head;
- length = (pfb->ram.size >> 12) - rsvd_head - rsvd_tail;
- return nouveau_mm_init(&pfb->vram, offset, length, 1);
- }
-
- /* otherwise, address lowest common amount from 0GiB */
- ret = nouveau_mm_init(&pfb->vram, rsvd_head, (bsize << 8) * parts, 1);
- if (ret)
- return ret;
-
- /* and the rest starting from (8GiB + common_size) */
- offset = (0x0200000000ULL >> 12) + (bsize << 8);
- length = (pfb->ram.size >> 12) - (bsize << 8) - rsvd_tail;
-
- ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
- if (ret) {
- nouveau_mm_fini(&pfb->vram);
- return ret;
- }
-
- return 0;
-}
-
-static int
-nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **pmem)
-{
- struct nouveau_mm *mm = &pfb->vram;
- struct nouveau_mm_node *r;
- struct nouveau_mem *mem;
- int type = (memtype & 0x0ff);
- int back = (memtype & 0x800);
- int ret;
- const bool comp = nvc0_pte_storage_type_map[type] != type;
-
- size >>= 12;
- align >>= 12;
- ncmin >>= 12;
- if (!ncmin)
- ncmin = size;
-
- mem = kzalloc(sizeof(*mem), GFP_KERNEL);
- if (!mem)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&mem->regions);
- mem->size = size;
-
- mutex_lock(&pfb->base.mutex);
- if (comp) {
- struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
-
- /* compression only works with lpages */
- if (align == (1 << (17 - 12))) {
- int n = size >> 5;
- ltcg->tags_alloc(ltcg, n, &mem->tag);
- }
- if (unlikely(!mem->tag))
- type = nvc0_pte_storage_type_map[type];
- }
- mem->memtype = type;
-
- do {
- if (back)
- ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
- else
- ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
- if (ret) {
- mutex_unlock(&pfb->base.mutex);
- pfb->ram.put(pfb, &mem);
- return ret;
- }
-
- list_add_tail(&r->rl_entry, &mem->regions);
- size -= r->length;
- } while (size);
- mutex_unlock(&pfb->base.mutex);
-
- r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
- mem->offset = (u64)r->offset << 12;
- *pmem = mem;
- return 0;
-}
-
-static void
-nvc0_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
-{
- struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
-
- if ((*pmem)->tag)
- ltcg->tags_free(ltcg, &(*pmem)->tag);
-
- nv50_fb_vram_del(pfb, pmem);
-}
-
-static int
nvc0_fb_init(struct nouveau_object *object)
{
struct nvc0_fb_priv *priv = (void *)object;
@@ -212,15 +78,12 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nvc0_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nouveau_fb_create(parent, engine, oclass, &nvc0_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.memtype_valid = nvc0_fb_memtype_valid;
- priv->base.ram.init = nvc0_fb_vram_init;
- priv->base.ram.get = nvc0_fb_vram_new;
- priv->base.ram.put = nvc0_fb_vram_del;
priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (priv->r100c10_page) {
@@ -231,7 +94,7 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return -EFAULT;
}
- return nouveau_fb_preinit(&priv->base);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
new file mode 100644
index 000000000000..6c974dd83e8b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
@@ -0,0 +1,87 @@
+#ifndef __NVKM_FB_PRIV_H__
+#define __NVKM_FB_PRIV_H__
+
+#include <subdev/fb.h>
+
+#define nouveau_ram_create(p,e,o,d) \
+ nouveau_object_create_((p), (e), (o), 0, sizeof(**d), (void **)d)
+#define nouveau_ram_destroy(p) \
+ nouveau_object_destroy(&(p)->base)
+#define nouveau_ram_init(p) \
+ nouveau_object_init(&(p)->base)
+#define nouveau_ram_fini(p,s) \
+ nouveau_object_fini(&(p)->base, (s))
+
+#define _nouveau_ram_dtor nouveau_object_destroy
+#define _nouveau_ram_init nouveau_object_init
+#define _nouveau_ram_fini nouveau_object_fini
+
+extern struct nouveau_oclass nv04_ram_oclass;
+extern struct nouveau_oclass nv10_ram_oclass;
+extern struct nouveau_oclass nv1a_ram_oclass;
+extern struct nouveau_oclass nv20_ram_oclass;
+extern struct nouveau_oclass nv40_ram_oclass;
+extern struct nouveau_oclass nv41_ram_oclass;
+extern struct nouveau_oclass nv44_ram_oclass;
+extern struct nouveau_oclass nv49_ram_oclass;
+extern struct nouveau_oclass nv4e_ram_oclass;
+extern struct nouveau_oclass nv50_ram_oclass;
+extern struct nouveau_oclass nvc0_ram_oclass;
+
+#define nouveau_fb_create(p,e,c,r,d) \
+ nouveau_fb_create_((p), (e), (c), (r), sizeof(**d), (void **)d)
+#define nouveau_fb_destroy(p) ({ \
+ struct nouveau_fb *pfb = (p); \
+ _nouveau_fb_dtor(nv_object(pfb)); \
+})
+#define nouveau_fb_init(p) ({ \
+ struct nouveau_fb *pfb = (p); \
+ _nouveau_fb_init(nv_object(pfb)); \
+})
+#define nouveau_fb_fini(p,s) ({ \
+ struct nouveau_fb *pfb = (p); \
+ _nouveau_fb_fini(nv_object(pfb), (s)); \
+})
+
+int nouveau_fb_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, struct nouveau_oclass *,
+ int length, void **pobject);
+void _nouveau_fb_dtor(struct nouveau_object *);
+int _nouveau_fb_init(struct nouveau_object *);
+int _nouveau_fb_fini(struct nouveau_object *, bool);
+
+struct nouveau_bios;
+int nouveau_fb_bios_memtype(struct nouveau_bios *);
+
+bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
+
+void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nouveau_fb_tile *);
+void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
+void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nouveau_fb_tile *);
+void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
+void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+int nv30_fb_init(struct nouveau_object *);
+void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nouveau_fb_tile *);
+
+void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags,
+ struct nouveau_fb_tile *);
+
+int nv41_fb_init(struct nouveau_object *);
+void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+int nv44_fb_init(struct nouveau_object *);
+void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nouveau_fb_tile *);
+
+void nv50_ram_put(struct nouveau_fb *, struct nouveau_mem **);
+extern int nv50_fb_memtype[0x80];
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c
new file mode 100644
index 000000000000..e781080d3327
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#define NV04_PFB_BOOT_0 0x00100000
+# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003
+# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004
+# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
+# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
+# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
+
+#include "priv.h"
+
+static int
+nv04_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ u32 boot0 = nv_rd32(pfb, NV04_PFB_BOOT_0);
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ if (boot0 & 0x00000100) {
+ ram->size = ((boot0 >> 12) & 0xf) * 2 + 2;
+ ram->size *= 1024 * 1024;
+ } else {
+ switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
+ ram->size = 32 * 1024 * 1024;
+ break;
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
+ ram->size = 16 * 1024 * 1024;
+ break;
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
+ ram->size = 8 * 1024 * 1024;
+ break;
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
+ ram->size = 4 * 1024 * 1024;
+ break;
+ }
+ }
+
+ if ((boot0 & 0x00000038) <= 0x10)
+ ram->type = NV_MEM_TYPE_SGRAM;
+ else
+ ram->type = NV_MEM_TYPE_SDRAM;
+ return 0;
+}
+
+struct nouveau_oclass
+nv04_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c
new file mode 100644
index 000000000000..8311f3774edf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv10_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ u32 cfg0 = nv_rd32(pfb, 0x100200);
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ if (cfg0 & 0x00000001)
+ ram->type = NV_MEM_TYPE_DDR1;
+ else
+ ram->type = NV_MEM_TYPE_SDRAM;
+
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ return 0;
+}
+
+
+struct nouveau_oclass
+nv10_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c
new file mode 100644
index 000000000000..d0caddfb9db0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv1a_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ struct pci_dev *bridge;
+ u32 mem, mib;
+ int ret;
+
+ bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+ if (!bridge) {
+ nv_fatal(pfb, "no bridge device\n");
+ return -ENODEV;
+ }
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ if (nv_device(pfb)->chipset == 0x1a) {
+ pci_read_config_dword(bridge, 0x7c, &mem);
+ mib = ((mem >> 6) & 31) + 1;
+ } else {
+ pci_read_config_dword(bridge, 0x84, &mem);
+ mib = ((mem >> 4) & 127) + 1;
+ }
+
+ ram->type = NV_MEM_TYPE_STOLEN;
+ ram->size = mib * 1024 * 1024;
+ return 0;
+}
+
+struct nouveau_oclass
+nv1a_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv1a_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c
new file mode 100644
index 000000000000..fdc11bba226d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv20_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ u32 pbus1218 = nv_rd32(pfb, 0x001218);
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ switch (pbus1218 & 0x00000300) {
+ case 0x00000000: ram->type = NV_MEM_TYPE_SDRAM; break;
+ case 0x00000100: ram->type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000200: ram->type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000300: ram->type = NV_MEM_TYPE_GDDR2; break;
+ }
+ ram->size = (nv_rd32(pfb, 0x10020c) & 0xff000000);
+ ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
+ return 0;
+}
+
+struct nouveau_oclass
+nv20_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv20_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
new file mode 100644
index 000000000000..ee49ac4dbdb6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ u32 pbus1218 = nv_rd32(pfb, 0x001218);
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ switch (pbus1218 & 0x00000300) {
+ case 0x00000000: ram->type = NV_MEM_TYPE_SDRAM; break;
+ case 0x00000100: ram->type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000200: ram->type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000300: ram->type = NV_MEM_TYPE_DDR2; break;
+ }
+
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
+ return 0;
+}
+
+
+struct nouveau_oclass
+nv40_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
new file mode 100644
index 000000000000..1dab7e12abab
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ u32 pfb474 = nv_rd32(pfb, 0x100474);
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ if (pfb474 & 0x00000004)
+ ram->type = NV_MEM_TYPE_GDDR3;
+ if (pfb474 & 0x00000002)
+ ram->type = NV_MEM_TYPE_DDR2;
+ if (pfb474 & 0x00000001)
+ ram->type = NV_MEM_TYPE_DDR1;
+
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
+ return 0;
+}
+
+struct nouveau_oclass
+nv41_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv41_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
new file mode 100644
index 000000000000..25fff842e5c1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ u32 pfb474 = nv_rd32(pfb, 0x100474);
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ if (pfb474 & 0x00000004)
+ ram->type = NV_MEM_TYPE_GDDR3;
+ if (pfb474 & 0x00000002)
+ ram->type = NV_MEM_TYPE_DDR2;
+ if (pfb474 & 0x00000001)
+ ram->type = NV_MEM_TYPE_DDR1;
+
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ return 0;
+}
+
+struct nouveau_oclass
+nv44_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv44_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
new file mode 100644
index 000000000000..19e3a9a63a02
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ u32 pfb914 = nv_rd32(pfb, 0x100914);
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ switch (pfb914 & 0x00000003) {
+ case 0x00000000: pfb->ram->type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000001: pfb->ram->type = NV_MEM_TYPE_DDR2; break;
+ case 0x00000002: pfb->ram->type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000003: break;
+ }
+
+ pfb->ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ pfb->ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+ pfb->ram->tags = nv_rd32(pfb, 0x100320);
+ return 0;
+}
+
+struct nouveau_oclass
+nv49_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv49_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c
new file mode 100644
index 000000000000..7192aa6e5577
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv4e_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ pfb->ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ pfb->ram->type = NV_MEM_TYPE_STOLEN;
+ return 0;
+}
+
+struct nouveau_oclass
+nv4e_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv4e_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
new file mode 100644
index 000000000000..af5aa7ee8ad9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <core/mm.h>
+#include "priv.h"
+
+void
+nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+{
+ struct nouveau_mm_node *this;
+ struct nouveau_mem *mem;
+
+ mem = *pmem;
+ *pmem = NULL;
+ if (unlikely(mem == NULL))
+ return;
+
+ mutex_lock(&pfb->base.mutex);
+ while (!list_empty(&mem->regions)) {
+ this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
+
+ list_del(&this->rl_entry);
+ nouveau_mm_free(&pfb->vram, &this);
+ }
+
+ nouveau_mm_free(&pfb->tags, &mem->tag);
+ mutex_unlock(&pfb->base.mutex);
+
+ kfree(mem);
+}
+
+static int
+nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nouveau_mem **pmem)
+{
+ struct nouveau_mm *heap = &pfb->vram;
+ struct nouveau_mm *tags = &pfb->tags;
+ struct nouveau_mm_node *r;
+ struct nouveau_mem *mem;
+ int comp = (memtype & 0x300) >> 8;
+ int type = (memtype & 0x07f);
+ int back = (memtype & 0x800);
+ int min, max, ret;
+
+ max = (size >> 12);
+ min = ncmin ? (ncmin >> 12) : max;
+ align >>= 12;
+
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
+
+ mutex_lock(&pfb->base.mutex);
+ if (comp) {
+ if (align == 16) {
+ int n = (max >> 4) * comp;
+
+ ret = nouveau_mm_head(tags, 1, n, n, 1, &mem->tag);
+ if (ret)
+ mem->tag = NULL;
+ }
+
+ if (unlikely(!mem->tag))
+ comp = 0;
+ }
+
+ INIT_LIST_HEAD(&mem->regions);
+ mem->memtype = (comp << 7) | type;
+ mem->size = max;
+
+ type = nv50_fb_memtype[type];
+ do {
+ if (back)
+ ret = nouveau_mm_tail(heap, type, max, min, align, &r);
+ else
+ ret = nouveau_mm_head(heap, type, max, min, align, &r);
+ if (ret) {
+ mutex_unlock(&pfb->base.mutex);
+ pfb->ram->put(pfb, &mem);
+ return ret;
+ }
+
+ list_add_tail(&r->rl_entry, &mem->regions);
+ max -= r->length;
+ } while (max);
+ mutex_unlock(&pfb->base.mutex);
+
+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+ mem->offset = (u64)r->offset << 12;
+ *pmem = mem;
+ return 0;
+}
+
+static u32
+nv50_fb_vram_rblock(struct nouveau_fb *pfb, struct nouveau_ram *ram)
+{
+ int i, parts, colbits, rowbitsa, rowbitsb, banks;
+ u64 rowsize, predicted;
+ u32 r0, r4, rt, ru, rblock_size;
+
+ r0 = nv_rd32(pfb, 0x100200);
+ r4 = nv_rd32(pfb, 0x100204);
+ rt = nv_rd32(pfb, 0x100250);
+ ru = nv_rd32(pfb, 0x001540);
+ nv_debug(pfb, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
+
+ for (i = 0, parts = 0; i < 8; i++) {
+ if (ru & (0x00010000 << i))
+ parts++;
+ }
+
+ colbits = (r4 & 0x0000f000) >> 12;
+ rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
+ rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
+ banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
+
+ rowsize = parts * banks * (1 << colbits) * 8;
+ predicted = rowsize << rowbitsa;
+ if (r0 & 0x00000004)
+ predicted += rowsize << rowbitsb;
+
+ if (predicted != ram->size) {
+ nv_warn(pfb, "memory controller reports %d MiB VRAM\n",
+ (u32)(ram->size >> 20));
+ }
+
+ rblock_size = rowsize;
+ if (rt & 1)
+ rblock_size *= 3;
+
+ nv_debug(pfb, "rblock %d bytes\n", rblock_size);
+ return rblock_size;
+}
+
+static int
+nv50_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 datasize,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_device *device = nv_device(pfb);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_ram *ram;
+ const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+ const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+ u32 size;
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ ram->size = nv_rd32(pfb, 0x10020c);
+ ram->size = (ram->size & 0xffffff00) |
+ ((ram->size & 0x000000ff) << 32);
+
+ size = (ram->size >> 12) - rsvd_head - rsvd_tail;
+ switch (device->chipset) {
+ case 0xaa:
+ case 0xac:
+ case 0xaf: /* IGPs, no reordering, no real VRAM */
+ ret = nouveau_mm_init(&pfb->vram, rsvd_head, size, 1);
+ if (ret)
+ return ret;
+
+ ram->type = NV_MEM_TYPE_STOLEN;
+ ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
+ break;
+ default:
+ switch (nv_rd32(pfb, 0x100714) & 0x00000007) {
+ case 0: ram->type = NV_MEM_TYPE_DDR1; break;
+ case 1:
+ if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
+ ram->type = NV_MEM_TYPE_DDR3;
+ else
+ ram->type = NV_MEM_TYPE_DDR2;
+ break;
+ case 2: ram->type = NV_MEM_TYPE_GDDR3; break;
+ case 3: ram->type = NV_MEM_TYPE_GDDR4; break;
+ case 4: ram->type = NV_MEM_TYPE_GDDR5; break;
+ default:
+ break;
+ }
+
+ ret = nouveau_mm_init(&pfb->vram, rsvd_head, size,
+ nv50_fb_vram_rblock(pfb, ram) >> 12);
+ if (ret)
+ return ret;
+
+ ram->ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
+ break;
+ }
+
+ ram->get = nv50_ram_get;
+ ram->put = nv50_ram_put;
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
new file mode 100644
index 000000000000..9c3634acbb9d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <subdev/ltcg.h>
+
+#include "priv.h"
+
+extern const u8 nvc0_pte_storage_type_map[256];
+
+void
+nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+{
+ struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb);
+
+ if ((*pmem)->tag)
+ ltcg->tags_free(ltcg, &(*pmem)->tag);
+
+ nv50_ram_put(pfb, pmem);
+}
+
+int
+nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nouveau_mem **pmem)
+{
+ struct nouveau_mm *mm = &pfb->vram;
+ struct nouveau_mm_node *r;
+ struct nouveau_mem *mem;
+ int type = (memtype & 0x0ff);
+ int back = (memtype & 0x800);
+ const bool comp = nvc0_pte_storage_type_map[type] != type;
+ int ret;
+
+ size >>= 12;
+ align >>= 12;
+ ncmin >>= 12;
+ if (!ncmin)
+ ncmin = size;
+
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&mem->regions);
+ mem->size = size;
+
+ mutex_lock(&pfb->base.mutex);
+ if (comp) {
+ struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb);
+
+ /* compression only works with lpages */
+ if (align == (1 << (17 - 12))) {
+ int n = size >> 5;
+ ltcg->tags_alloc(ltcg, n, &mem->tag);
+ }
+
+ if (unlikely(!mem->tag))
+ type = nvc0_pte_storage_type_map[type];
+ }
+ mem->memtype = type;
+
+ do {
+ if (back)
+ ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
+ else
+ ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
+ if (ret) {
+ mutex_unlock(&pfb->base.mutex);
+ pfb->ram->put(pfb, &mem);
+ return ret;
+ }
+
+ list_add_tail(&r->rl_entry, &mem->regions);
+ size -= r->length;
+ } while (size);
+ mutex_unlock(&pfb->base.mutex);
+
+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+ mem->offset = (u64)r->offset << 12;
+ *pmem = mem;
+ return 0;
+}
+
+static int
+nvc0_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_bios *bios = nouveau_bios(pfb);
+ struct nouveau_ram *ram;
+ const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+ const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+ u32 parts = nv_rd32(pfb, 0x022438);
+ u32 pmask = nv_rd32(pfb, 0x022554);
+ u32 bsize = nv_rd32(pfb, 0x10f20c);
+ u32 offset, length;
+ bool uniform = true;
+ int ret, part;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ nv_debug(pfb, "0x100800: 0x%08x\n", nv_rd32(pfb, 0x100800));
+ nv_debug(pfb, "parts 0x%08x mask 0x%08x\n", parts, pmask);
+
+ ram->type = nouveau_fb_bios_memtype(bios);
+ ram->ranks = (nv_rd32(pfb, 0x10f200) & 0x00000004) ? 2 : 1;
+
+ /* read amount of vram attached to each memory controller */
+ for (part = 0; part < parts; part++) {
+ if (!(pmask & (1 << part))) {
+ u32 psize = nv_rd32(pfb, 0x11020c + (part * 0x1000));
+ if (psize != bsize) {
+ if (psize < bsize)
+ bsize = psize;
+ uniform = false;
+ }
+
+ nv_debug(pfb, "%d: mem_amount 0x%08x\n", part, psize);
+ ram->size += (u64)psize << 20;
+ }
+ }
+
+ /* if all controllers have the same amount attached, there's no holes */
+ if (uniform) {
+ offset = rsvd_head;
+ length = (ram->size >> 12) - rsvd_head - rsvd_tail;
+ ret = nouveau_mm_init(&pfb->vram, offset, length, 1);
+ } else {
+ /* otherwise, address lowest common amount from 0GiB */
+ ret = nouveau_mm_init(&pfb->vram, rsvd_head,
+ (bsize << 8) * parts, 1);
+ if (ret)
+ return ret;
+
+ /* and the rest starting from (8GiB + common_size) */
+ offset = (0x0200000000ULL >> 12) + (bsize << 8);
+ length = (ram->size >> 12) - (bsize << 8) - rsvd_tail;
+
+ ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
+ if (ret)
+ nouveau_mm_fini(&pfb->vram);
+ }
+
+ if (ret)
+ return ret;
+
+ ram->get = nvc0_ram_get;
+ ram->put = nvc0_ram_put;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_ram_oclass = {
+ .handle = 0,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_ram_create,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
index cfc7e31461de..97bc5dff93e7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
@@ -56,7 +56,7 @@ nv50_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- ret = pfb->ram.get(pfb, size, align, 0, 0x800, &node->mem);
+ ret = pfb->ram->get(pfb, size, align, 0, 0x800, &node->mem);
if (ret)
return ret;
@@ -71,7 +71,7 @@ nv50_instobj_dtor(struct nouveau_object *object)
{
struct nv50_instobj_priv *node = (void *)object;
struct nouveau_fb *pfb = nouveau_fb(object);
- pfb->ram.put(pfb, &node->mem);
+ pfb->ram->put(pfb, &node->mem);
nouveau_instobj_destroy(&node->base);
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
index fb794e997fbc..bcca883018f4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
@@ -122,7 +122,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
nv_wr32(priv, 0x17e000, priv->part_nr);
/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
- priv->num_tags = (pfb->ram.size >> 17) / 4;
+ priv->num_tags = (pfb->ram->size >> 17) / 4;
if (priv->num_tags > (1 << 17))
priv->num_tags = 1 << 17; /* we have 17 bits in PTE */
priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
index d796924f9930..0cb322a5e72c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
@@ -35,6 +35,7 @@ nv50_mc_intr[] = {
{ 0x00001000, NVDEV_ENGINE_GR },
{ 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84- */
{ 0x00008000, NVDEV_ENGINE_BSP }, /* NV84- */
+ { 0x00020000, NVDEV_ENGINE_VP }, /* NV84- */
{ 0x00100000, NVDEV_SUBDEV_TIMER },
{ 0x00200000, NVDEV_SUBDEV_GPIO },
{ 0x04000000, NVDEV_ENGINE_DISP },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
index 737bd4b682e1..c5da3babbc62 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
@@ -33,6 +33,7 @@ nvc0_mc_intr[] = {
{ 0x00000001, NVDEV_ENGINE_PPP },
{ 0x00000020, NVDEV_ENGINE_COPY0 },
{ 0x00000040, NVDEV_ENGINE_COPY1 },
+ { 0x00000080, NVDEV_ENGINE_COPY2 },
{ 0x00000100, NVDEV_ENGINE_FIFO },
{ 0x00001000, NVDEV_ENGINE_GR },
{ 0x00008000, NVDEV_ENGINE_BSP },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
index 77c67fc970e6..34d3fbfbd631 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
@@ -236,9 +236,9 @@ nouveau_vm_unmap_pgt(struct nouveau_vm *vm, int big, u32 fpde, u32 lpde)
vmm->map_pgt(vpgd->obj, pde, vpgt->obj);
}
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
nouveau_gpuobj_ref(NULL, &pgt);
- mutex_lock(&vm->mm.mutex);
+ mutex_lock(&nv_subdev(vmm)->mutex);
}
}
@@ -256,18 +256,18 @@ nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type)
pgt_size = (1 << (vmm->pgt_bits + 12)) >> type;
pgt_size *= 8;
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
ret = nouveau_gpuobj_new(nv_object(vm->vmm), NULL, pgt_size, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC, &pgt);
- mutex_lock(&vm->mm.mutex);
+ mutex_lock(&nv_subdev(vmm)->mutex);
if (unlikely(ret))
return ret;
/* someone beat us to filling the PDE while we didn't have the lock */
if (unlikely(vpgt->refcount[big]++)) {
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
nouveau_gpuobj_ref(NULL, &pgt);
- mutex_lock(&vm->mm.mutex);
+ mutex_lock(&nv_subdev(vmm)->mutex);
return 0;
}
@@ -289,11 +289,11 @@ nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift,
u32 fpde, lpde, pde;
int ret;
- mutex_lock(&vm->mm.mutex);
+ mutex_lock(&nv_subdev(vmm)->mutex);
ret = nouveau_mm_head(&vm->mm, page_shift, msize, msize, align,
&vma->node);
if (unlikely(ret != 0)) {
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
return ret;
}
@@ -314,13 +314,14 @@ nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift,
if (pde != fpde)
nouveau_vm_unmap_pgt(vm, big, fpde, pde - 1);
nouveau_mm_free(&vm->mm, &vma->node);
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
return ret;
}
}
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
- vma->vm = vm;
+ vma->vm = NULL;
+ nouveau_vm_ref(vm, &vma->vm, NULL);
vma->offset = (u64)vma->node->offset << 12;
vma->access = access;
return 0;
@@ -338,10 +339,12 @@ nouveau_vm_put(struct nouveau_vma *vma)
fpde = (vma->node->offset >> vmm->pgt_bits);
lpde = (vma->node->offset + vma->node->length - 1) >> vmm->pgt_bits;
- mutex_lock(&vm->mm.mutex);
+ mutex_lock(&nv_subdev(vmm)->mutex);
nouveau_vm_unmap_pgt(vm, vma->node->type != vmm->spg_shift, fpde, lpde);
nouveau_mm_free(&vm->mm, &vma->node);
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
+
+ nouveau_vm_ref(NULL, &vma->vm, NULL);
}
int
@@ -405,24 +408,25 @@ nouveau_vm_link(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd)
nouveau_gpuobj_ref(pgd, &vpgd->obj);
- mutex_lock(&vm->mm.mutex);
+ mutex_lock(&nv_subdev(vmm)->mutex);
for (i = vm->fpde; i <= vm->lpde; i++)
vmm->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj);
list_add(&vpgd->head, &vm->pgd_list);
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
return 0;
}
static void
nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd)
{
+ struct nouveau_vmmgr *vmm = vm->vmm;
struct nouveau_vm_pgd *vpgd, *tmp;
struct nouveau_gpuobj *pgd = NULL;
if (!mpgd)
return;
- mutex_lock(&vm->mm.mutex);
+ mutex_lock(&nv_subdev(vmm)->mutex);
list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
if (vpgd->obj == mpgd) {
pgd = vpgd->obj;
@@ -431,7 +435,7 @@ nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd)
break;
}
}
- mutex_unlock(&vm->mm.mutex);
+ mutex_unlock(&nv_subdev(vmm)->mutex);
nouveau_gpuobj_ref(NULL, &pgd);
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
index e067f81c97b3..07dd1fe2d6fb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
@@ -27,11 +27,11 @@
#include <subdev/timer.h>
#include <subdev/fb.h>
+#include <subdev/bar.h>
#include <subdev/vm.h>
struct nv50_vmmgr_priv {
struct nouveau_vmmgr base;
- spinlock_t lock;
};
static void
@@ -86,8 +86,8 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
/* IGPs don't have real VRAM, re-target to stolen system memory */
target = 0;
- if (nouveau_fb(vma->vm->vmm)->ram.stolen) {
- phys += nouveau_fb(vma->vm->vmm)->ram.stolen;
+ if (nouveau_fb(vma->vm->vmm)->ram->stolen) {
+ phys += nouveau_fb(vma->vm->vmm)->ram->stolen;
target = 3;
}
@@ -151,29 +151,42 @@ nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
static void
nv50_vm_flush(struct nouveau_vm *vm)
{
+ struct nv50_vmmgr_priv *priv = (void *)vm->vmm;
+ struct nouveau_bar *bar = nouveau_bar(priv);
struct nouveau_engine *engine;
- int i;
+ int i, vme;
+
+ bar->flush(bar);
+ mutex_lock(&nv_subdev(priv)->mutex);
for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
- if (atomic_read(&vm->engref[i])) {
- engine = nouveau_engine(vm->vmm, i);
- if (engine && engine->tlb_flush)
- engine->tlb_flush(engine);
+ if (!atomic_read(&vm->engref[i]))
+ continue;
+
+ /* unfortunate hw bug workaround... */
+ engine = nouveau_engine(priv, i);
+ if (engine && engine->tlb_flush) {
+ engine->tlb_flush(engine);
+ continue;
}
- }
-}
-void
-nv50_vm_flush_engine(struct nouveau_subdev *subdev, int engine)
-{
- struct nv50_vmmgr_priv *priv = (void *)nouveau_vmmgr(subdev);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- nv_wr32(subdev, 0x100c80, (engine << 16) | 1);
- if (!nv_wait(subdev, 0x100c80, 0x00000001, 0x00000000))
- nv_error(subdev, "vm flush timeout: engine %d\n", engine);
- spin_unlock_irqrestore(&priv->lock, flags);
+ switch (i) {
+ case NVDEV_ENGINE_GR : vme = 0x00; break;
+ case NVDEV_ENGINE_VP : vme = 0x01; break;
+ case NVDEV_SUBDEV_BAR : vme = 0x06; break;
+ case NVDEV_ENGINE_MPEG : vme = 0x08; break;
+ case NVDEV_ENGINE_BSP : vme = 0x09; break;
+ case NVDEV_ENGINE_CRYPT: vme = 0x0a; break;
+ case NVDEV_ENGINE_COPY0: vme = 0x0d; break;
+ default:
+ continue;
+ }
+
+ nv_wr32(priv, 0x100c80, (vme << 16) | 1);
+ if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000))
+ nv_error(priv, "vm flush timeout: engine %d\n", vme);
+ }
+ mutex_unlock(&nv_subdev(priv)->mutex);
}
static int
@@ -211,7 +224,6 @@ nv50_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.map_sg = nv50_vm_map_sg;
priv->base.unmap = nv50_vm_unmap;
priv->base.flush = nv50_vm_flush;
- spin_lock_init(&priv->lock);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
index 4c3b0a23b9d6..668cf964e4a9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
@@ -29,10 +29,10 @@
#include <subdev/fb.h>
#include <subdev/vm.h>
#include <subdev/ltcg.h>
+#include <subdev/bar.h>
struct nvc0_vmmgr_priv {
struct nouveau_vmmgr base;
- spinlock_t lock;
};
@@ -160,40 +160,40 @@ nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
}
-void
-nvc0_vm_flush_engine(struct nouveau_subdev *subdev, u64 addr, int type)
-{
- struct nvc0_vmmgr_priv *priv = (void *)nouveau_vmmgr(subdev);
- unsigned long flags;
-
- /* looks like maybe a "free flush slots" counter, the
- * faster you write to 0x100cbc to more it decreases
- */
- spin_lock_irqsave(&priv->lock, flags);
- if (!nv_wait_ne(subdev, 0x100c80, 0x00ff0000, 0x00000000)) {
- nv_error(subdev, "vm timeout 0: 0x%08x %d\n",
- nv_rd32(subdev, 0x100c80), type);
- }
-
- nv_wr32(subdev, 0x100cb8, addr >> 8);
- nv_wr32(subdev, 0x100cbc, 0x80000000 | type);
-
- /* wait for flush to be queued? */
- if (!nv_wait(subdev, 0x100c80, 0x00008000, 0x00008000)) {
- nv_error(subdev, "vm timeout 1: 0x%08x %d\n",
- nv_rd32(subdev, 0x100c80), type);
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
static void
nvc0_vm_flush(struct nouveau_vm *vm)
{
+ struct nvc0_vmmgr_priv *priv = (void *)vm->vmm;
+ struct nouveau_bar *bar = nouveau_bar(priv);
struct nouveau_vm_pgd *vpgd;
+ u32 type;
+
+ bar->flush(bar);
+
+ type = 0x00000001; /* PAGE_ALL */
+ if (atomic_read(&vm->engref[NVDEV_SUBDEV_BAR]))
+ type |= 0x00000004; /* HUB_ONLY */
+ mutex_lock(&nv_subdev(priv)->mutex);
list_for_each_entry(vpgd, &vm->pgd_list, head) {
- nvc0_vm_flush_engine(nv_subdev(vm->vmm), vpgd->obj->addr, 1);
+ /* looks like maybe a "free flush slots" counter, the
+ * faster you write to 0x100cbc to more it decreases
+ */
+ if (!nv_wait_ne(priv, 0x100c80, 0x00ff0000, 0x00000000)) {
+ nv_error(priv, "vm timeout 0: 0x%08x %d\n",
+ nv_rd32(priv, 0x100c80), type);
+ }
+
+ nv_wr32(priv, 0x100cb8, vpgd->obj->addr >> 8);
+ nv_wr32(priv, 0x100cbc, 0x80000000 | type);
+
+ /* wait for flush to be queued? */
+ if (!nv_wait(priv, 0x100c80, 0x00008000, 0x00008000)) {
+ nv_error(priv, "vm timeout 1: 0x%08x %d\n",
+ nv_rd32(priv, 0x100c80), type);
+ }
}
+ mutex_unlock(&nv_subdev(priv)->mutex);
}
static int
@@ -227,7 +227,6 @@ nvc0_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.map_sg = nvc0_vm_map_sg;
priv->base.unmap = nvc0_vm_unmap;
priv->base.flush = nvc0_vm_flush;
- spin_lock_init(&priv->lock);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 6aa2137e093a..3e7287675ecf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -1878,9 +1878,6 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
if (dcb->version < 0x21)
merge_like_dcb_entries(dev, dcb);
- if (!dcb->entries)
- return -ENXIO;
-
/* dump connector table entries to log, if any exist */
idx = -1;
while ((conn = olddcb_conn(dev, ++idx))) {
@@ -2054,19 +2051,14 @@ nouveau_bios_posted(struct drm_device *dev)
struct nouveau_drm *drm = nouveau_drm(dev);
unsigned htotal;
- if (nv_device(drm->device)->card_type >= NV_50) {
- if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
- NVReadVgaCrtc(dev, 0, 0x1a) == 0)
- return false;
+ if (nv_device(drm->device)->card_type >= NV_50)
return true;
- }
htotal = NVReadVgaCrtc(dev, 0, 0x06);
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
-
return (htotal != 0);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7ff10711a4d0..a1cf8255db50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -255,7 +255,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
{
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct nouveau_fb *pfb = nouveau_fb(drm->device);
- u32 vram_pages = pfb->ram.size >> PAGE_SHIFT;
+ u32 vram_pages = pfb->ram->size >> PAGE_SHIFT;
if (nv_device(drm->device)->card_type == NV_10 &&
nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
@@ -1550,13 +1550,8 @@ void
nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
{
if (vma->node) {
- if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM) {
- spin_lock(&nvbo->bo.bdev->fence_lock);
- ttm_bo_wait(&nvbo->bo, false, false, false);
- spin_unlock(&nvbo->bo.bdev->fence_lock);
+ if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM)
nouveau_vm_unmap(vma);
- }
-
nouveau_vm_put(vma);
list_del(&vma->head);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index eaa80a2b81ee..e84f4c32331b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -147,7 +147,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli,
args.limit = client->vm->vmm->limit - 1;
} else
if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) {
- u64 limit = pfb->ram.size - imem->reserved - 1;
+ u64 limit = pfb->ram->size - imem->reserved - 1;
if (device->card_type == NV_04) {
/* nv04 vram pushbuf hack, retarget to its location in
* the framebuffer bar rather than direct vram access..
@@ -282,7 +282,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
} else {
args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR;
args.start = 0;
- args.limit = pfb->ram.size - imem->reserved - 1;
+ args.limit = pfb->ram->size - imem->reserved - 1;
}
ret = nouveau_object_new(nv_object(client), chan->handle, vram,
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 87afb0cb39cb..708b2d1c0037 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -333,10 +333,15 @@ nouveau_display_create(struct drm_device *dev)
if (nouveau_modeset == 1 ||
(nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) {
- if (nv_device(drm->device)->card_type < NV_50)
- ret = nv04_display_create(dev);
- else
- ret = nv50_display_create(dev);
+ if (drm->vbios.dcb.entries) {
+ if (nv_device(drm->device)->card_type < NV_50)
+ ret = nv04_display_create(dev);
+ else
+ ret = nv50_display_create(dev);
+ } else {
+ ret = 0;
+ }
+
if (ret)
goto disp_create_err;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index ecbfe691400c..9352010030e9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -472,10 +472,10 @@ nouveau_fbcon_init(struct drm_device *dev)
drm_fb_helper_single_add_all_connectors(&fbcon->helper);
- if (pfb->ram.size <= 32 * 1024 * 1024)
+ if (pfb->ram->size <= 32 * 1024 * 1024)
preferred_bpp = 8;
else
- if (pfb->ram.size <= 64 * 1024 * 1024)
+ if (pfb->ram->size <= 64 * 1024 * 1024)
preferred_bpp = 16;
else
preferred_bpp = 32;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 6c946837a0aa..1680d9187bab 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -35,15 +35,34 @@
#include <engine/fifo.h>
+struct fence_work {
+ struct work_struct base;
+ struct list_head head;
+ void (*func)(void *);
+ void *data;
+};
+
+static void
+nouveau_fence_signal(struct nouveau_fence *fence)
+{
+ struct fence_work *work, *temp;
+
+ list_for_each_entry_safe(work, temp, &fence->work, head) {
+ schedule_work(&work->base);
+ list_del(&work->head);
+ }
+
+ fence->channel = NULL;
+ list_del(&fence->head);
+}
+
void
nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
{
struct nouveau_fence *fence, *fnext;
spin_lock(&fctx->lock);
list_for_each_entry_safe(fence, fnext, &fctx->pending, head) {
- fence->channel = NULL;
- list_del(&fence->head);
- nouveau_fence_unref(&fence);
+ nouveau_fence_signal(fence);
}
spin_unlock(&fctx->lock);
}
@@ -57,6 +76,50 @@ nouveau_fence_context_new(struct nouveau_fence_chan *fctx)
}
static void
+nouveau_fence_work_handler(struct work_struct *kwork)
+{
+ struct fence_work *work = container_of(kwork, typeof(*work), base);
+ work->func(work->data);
+ kfree(work);
+}
+
+void
+nouveau_fence_work(struct nouveau_fence *fence,
+ void (*func)(void *), void *data)
+{
+ struct nouveau_channel *chan = fence->channel;
+ struct nouveau_fence_chan *fctx;
+ struct fence_work *work = NULL;
+
+ if (nouveau_fence_done(fence)) {
+ func(data);
+ return;
+ }
+
+ fctx = chan->fence;
+ work = kmalloc(sizeof(*work), GFP_KERNEL);
+ if (!work) {
+ WARN_ON(nouveau_fence_wait(fence, false, false));
+ func(data);
+ return;
+ }
+
+ spin_lock(&fctx->lock);
+ if (!fence->channel) {
+ spin_unlock(&fctx->lock);
+ kfree(work);
+ func(data);
+ return;
+ }
+
+ INIT_WORK(&work->base, nouveau_fence_work_handler);
+ work->func = func;
+ work->data = data;
+ list_add(&work->head, &fence->work);
+ spin_unlock(&fctx->lock);
+}
+
+static void
nouveau_fence_update(struct nouveau_channel *chan)
{
struct nouveau_fence_chan *fctx = chan->fence;
@@ -67,8 +130,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
if (fctx->read(chan) < fence->sequence)
break;
- fence->channel = NULL;
- list_del(&fence->head);
+ nouveau_fence_signal(fence);
nouveau_fence_unref(&fence);
}
spin_unlock(&fctx->lock);
@@ -265,6 +327,7 @@ nouveau_fence_new(struct nouveau_channel *chan, bool sysmem,
if (!fence)
return -ENOMEM;
+ INIT_LIST_HEAD(&fence->work);
fence->sysmem = sysmem;
kref_init(&fence->kref);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
index c89943407b52..c57bb61da58c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -5,6 +5,7 @@ struct nouveau_drm;
struct nouveau_fence {
struct list_head head;
+ struct list_head work;
struct kref kref;
bool sysmem;
@@ -22,6 +23,7 @@ void nouveau_fence_unref(struct nouveau_fence **);
int nouveau_fence_emit(struct nouveau_fence *, struct nouveau_channel *);
bool nouveau_fence_done(struct nouveau_fence *);
+void nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
int nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr);
int nouveau_fence_sync(struct nouveau_fence *, struct nouveau_channel *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 2b2077d1e2f7..e72d09c068a8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -102,6 +102,41 @@ out:
return ret;
}
+static void
+nouveau_gem_object_delete(void *data)
+{
+ struct nouveau_vma *vma = data;
+ nouveau_vm_unmap(vma);
+ nouveau_vm_put(vma);
+ kfree(vma);
+}
+
+static void
+nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
+{
+ const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM;
+ struct nouveau_fence *fence = NULL;
+
+ list_del(&vma->head);
+
+ if (mapped) {
+ spin_lock(&nvbo->bo.bdev->fence_lock);
+ if (nvbo->bo.sync_obj)
+ fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+ spin_unlock(&nvbo->bo.bdev->fence_lock);
+ }
+
+ if (fence) {
+ nouveau_fence_work(fence, nouveau_gem_object_delete, vma);
+ } else {
+ if (mapped)
+ nouveau_vm_unmap(vma);
+ nouveau_vm_put(vma);
+ kfree(vma);
+ }
+ nouveau_fence_unref(&fence);
+}
+
void
nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
{
@@ -119,10 +154,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
if (vma) {
- if (--vma->refcount == 0) {
- nouveau_bo_vma_del(nvbo, vma);
- kfree(vma);
- }
+ if (--vma->refcount == 0)
+ nouveau_gem_object_unmap(nvbo, vma);
}
ttm_bo_unreserve(&nvbo->bo);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 7e0ff10a2759..4f6a572f2258 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -125,7 +125,7 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
t->reg[7] = 0x4000202 | (e->tCL - 1) << 16;
/* XXX: P.version == 1 only has DDR2 and GDDR3? */
- if (pfb->ram.type == NV_MEM_TYPE_DDR2) {
+ if (pfb->ram->type == NV_MEM_TYPE_DDR2) {
t->reg[5] |= (e->tCL + 3) << 8;
t->reg[6] |= (t->tCWL - 2) << 8;
t->reg[8] |= (e->tCL - 4);
@@ -428,7 +428,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
break;
}
- switch (pfb->ram.type * !ret) {
+ switch (pfb->ram->type * !ret) {
case NV_MEM_TYPE_GDDR3:
ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
break;
@@ -455,7 +455,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
else
dll_off = !!(ramcfg[2] & 0x40);
- switch (pfb->ram.type) {
+ switch (pfb->ram->type) {
case NV_MEM_TYPE_GDDR3:
t->mr[1] &= ~0x00000040;
t->mr[1] |= 0x00000040 * dll_off;
@@ -522,7 +522,7 @@ nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
t->odt = 0;
t->drive_strength = 0;
- switch (pfb->ram.type) {
+ switch (pfb->ram->type) {
case NV_MEM_TYPE_DDR3:
t->odt |= (t->mr[1] & 0x200) >> 7;
case NV_MEM_TYPE_DDR2:
@@ -551,7 +551,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] };
u32 mr1_dlloff;
- switch (pfb->ram.type) {
+ switch (pfb->ram->type) {
case NV_MEM_TYPE_DDR2:
tDLLK = 2000;
mr1_dlloff = 0x00000001;
@@ -572,7 +572,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
}
/* fetch current MRs */
- switch (pfb->ram.type) {
+ switch (pfb->ram->type) {
case NV_MEM_TYPE_GDDR3:
case NV_MEM_TYPE_DDR3:
mr[2] = exec->mrg(exec, 2);
@@ -639,7 +639,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
exec->mrs (exec, 0, info->mr[0] | 0x00000000);
exec->wait(exec, tMRD);
exec->wait(exec, tDLLK);
- if (pfb->ram.type == NV_MEM_TYPE_GDDR3)
+ if (pfb->ram->type == NV_MEM_TYPE_GDDR3)
exec->precharge(exec);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 3da985eb38cc..19e3757291fb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -69,7 +69,7 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
struct nouveau_drm *drm = nouveau_bdev(man->bdev);
struct nouveau_fb *pfb = nouveau_fb(drm->device);
nouveau_mem_node_cleanup(mem->mm_node);
- pfb->ram.put(pfb, (struct nouveau_mem **)&mem->mm_node);
+ pfb->ram->put(pfb, (struct nouveau_mem **)&mem->mm_node);
}
static int
@@ -88,7 +88,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
size_nc = 1 << nvbo->page_shift;
- ret = pfb->ram.get(pfb, mem->num_pages << PAGE_SHIFT,
+ ret = pfb->ram->get(pfb, mem->num_pages << PAGE_SHIFT,
mem->page_alignment << PAGE_SHIFT, size_nc,
(nvbo->tile_flags >> 8) & 0x3ff, &node);
if (ret) {
@@ -111,7 +111,7 @@ nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
struct nouveau_mm_node *r;
u32 total = 0, free = 0;
- mutex_lock(&mm->mutex);
+ mutex_lock(&nv_subdev(pfb)->mutex);
list_for_each_entry(r, &mm->nodes, nl_entry) {
printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n",
prefix, r->type, ((u64)r->offset << 12),
@@ -121,7 +121,7 @@ nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
if (!r->type)
free += r->length;
}
- mutex_unlock(&mm->mutex);
+ mutex_unlock(&nv_subdev(pfb)->mutex);
printk(KERN_DEBUG "%s total: 0x%010llx free: 0x%010llx\n",
prefix, (u64)total << 12, (u64)free << 12);
@@ -168,9 +168,6 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct nouveau_mem *node;
- if (unlikely((mem->num_pages << PAGE_SHIFT) >= 512 * 1024 * 1024))
- return -ENOMEM;
-
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return -ENOMEM;
@@ -386,7 +383,7 @@ nouveau_ttm_init(struct nouveau_drm *drm)
}
/* VRAM init */
- drm->gem.vram_available = nouveau_fb(drm->device)->ram.size;
+ drm->gem.vram_available = nouveau_fb(drm->device)->ram->size;
drm->gem.vram_available -= nouveau_instmem(drm->device)->reserved;
ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_VRAM,
@@ -402,8 +399,6 @@ nouveau_ttm_init(struct nouveau_drm *drm)
/* GART init */
if (drm->agp.stat != ENABLED) {
drm->gem.gart_available = nouveau_vmmgr(drm->device)->limit;
- if (drm->gem.gart_available > 512 * 1024 * 1024)
- drm->gem.gart_available = 512 * 1024 * 1024;
} else {
drm->gem.gart_available = drm->agp.size;
}
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index dd5e01f89f28..54dc6355b0c2 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -159,7 +159,7 @@ nv50_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NV50_DMA_CONF0_ENABLE |
NV50_DMA_CONF0_PART_256,
}, sizeof(struct nv_dma_class), &object);
@@ -172,7 +172,7 @@ nv50_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NV50_DMA_CONF0_ENABLE | 0x70 |
NV50_DMA_CONF0_PART_256,
}, sizeof(struct nv_dma_class), &object);
@@ -185,7 +185,7 @@ nv50_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NV50_DMA_CONF0_ENABLE | 0x7a |
NV50_DMA_CONF0_PART_256,
}, sizeof(struct nv_dma_class), &object);
@@ -204,7 +204,7 @@ nvc0_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NVC0_DMA_CONF0_ENABLE,
}, sizeof(struct nv_dma_class), &object);
if (ret)
@@ -216,7 +216,7 @@ nvc0_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NVC0_DMA_CONF0_ENABLE | 0xfe,
}, sizeof(struct nv_dma_class), &object);
if (ret)
@@ -228,7 +228,7 @@ nvc0_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NVC0_DMA_CONF0_ENABLE | 0xfe,
}, sizeof(struct nv_dma_class), &object);
return ret;
@@ -246,7 +246,7 @@ nvd0_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NVD0_DMA_CONF0_ENABLE |
NVD0_DMA_CONF0_PAGE_LP,
}, sizeof(struct nv_dma_class), &object);
@@ -259,7 +259,7 @@ nvd0_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
.conf0 = NVD0_DMA_CONF0_ENABLE | 0xfe |
NVD0_DMA_CONF0_PAGE_LP,
}, sizeof(struct nv_dma_class), &object);
@@ -316,7 +316,7 @@ nv50_dmac_create(struct nouveau_object *core, u32 bclass, u8 head,
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = 0,
- .limit = pfb->ram.size - 1,
+ .limit = pfb->ram->size - 1,
}, sizeof(struct nv_dma_class), &object);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index 69620e39c90c..4efc33fa73fc 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -493,12 +493,12 @@ mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
struct hwsq_ucode *hwsq = &info->mclk_hwsq;
if (mr <= 1) {
- if (pfb->ram.ranks > 1)
+ if (pfb->ram->ranks > 1)
hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data);
hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data);
} else
if (mr <= 3) {
- if (pfb->ram.ranks > 1)
+ if (pfb->ram->ranks > 1)
hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data);
hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data);
}
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c
index 863f010fafeb..0d0ed597fea8 100644
--- a/drivers/gpu/drm/nouveau/nva3_pm.c
+++ b/drivers/gpu/drm/nouveau/nva3_pm.c
@@ -389,12 +389,12 @@ mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
struct nouveau_device *device = nouveau_dev(exec->dev);
struct nouveau_fb *pfb = nouveau_fb(device);
if (mr <= 1) {
- if (pfb->ram.ranks > 1)
+ if (pfb->ram->ranks > 1)
nv_wr32(device, 0x1002c8 + ((mr - 0) * 4), data);
nv_wr32(device, 0x1002c0 + ((mr - 0) * 4), data);
} else
if (mr <= 3) {
- if (pfb->ram.ranks > 1)
+ if (pfb->ram->ranks > 1)
nv_wr32(device, 0x1002e8 + ((mr - 2) * 4), data);
nv_wr32(device, 0x1002e0 + ((mr - 2) * 4), data);
}
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c
index 0d34eb581179..3b7041cb013f 100644
--- a/drivers/gpu/drm/nouveau/nvc0_pm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_pm.c
@@ -477,7 +477,7 @@ mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
{
struct nouveau_device *device = nouveau_dev(exec->dev);
struct nouveau_fb *pfb = nouveau_fb(device);
- if (pfb->ram.type != NV_MEM_TYPE_GDDR5) {
+ if (pfb->ram->type != NV_MEM_TYPE_GDDR5) {
if (mr <= 1)
return nv_rd32(device, 0x10f300 + ((mr - 0) * 4));
return nv_rd32(device, 0x10f320 + ((mr - 2) * 4));
@@ -496,15 +496,15 @@ mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
{
struct nouveau_device *device = nouveau_dev(exec->dev);
struct nouveau_fb *pfb = nouveau_fb(device);
- if (pfb->ram.type != NV_MEM_TYPE_GDDR5) {
+ if (pfb->ram->type != NV_MEM_TYPE_GDDR5) {
if (mr <= 1) {
nv_wr32(device, 0x10f300 + ((mr - 0) * 4), data);
- if (pfb->ram.ranks > 1)
+ if (pfb->ram->ranks > 1)
nv_wr32(device, 0x10f308 + ((mr - 0) * 4), data);
} else
if (mr <= 3) {
nv_wr32(device, 0x10f320 + ((mr - 2) * 4), data);
- if (pfb->ram.ranks > 1)
+ if (pfb->ram->ranks > 1)
nv_wr32(device, 0x10f328 + ((mr - 2) * 4), data);
}
} else {
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index bab018583417..f072660c7665 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -2326,14 +2326,11 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)
return ret;
}
-#if 0
- /* XXX */
ret = rv770_unrestrict_performance_levels_after_switch(rdev);
if (ret) {
DRM_ERROR("rv770_unrestrict_performance_levels_after_switch failed\n");
return ret;
}
-#endif
return 0;
}
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 0de5b74f0287..2e1de4fd2975 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -4043,8 +4043,6 @@ static void evergreen_rlc_start(struct radeon_device *rdev)
if (rdev->flags & RADEON_IS_IGP) {
mask |= GFX_POWER_GATING_ENABLE | GFX_POWER_GATING_SRC;
- if (rdev->family == CHIP_ARUBA)
- mask |= DYN_PER_SIMD_PG_ENABLE | LB_CNT_SPIM_ACTIVE | LOAD_BALANCE_ENABLE;
}
WREG32(RLC_CNTL, mask);
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 777d17e61312..a4cb99c2da85 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -28,6 +28,7 @@
#include "ni_dpm.h"
#include "atom.h"
#include <linux/math64.h>
+#include <linux/seq_file.h>
#define MC_CG_ARB_FREQ_F0 0x0a
#define MC_CG_ARB_FREQ_F1 0x0b
@@ -1036,7 +1037,6 @@ static int ni_restrict_performance_levels_before_switch(struct radeon_device *rd
0 : -EINVAL;
}
-#if 0
static int ni_unrestrict_performance_levels_after_switch(struct radeon_device *rdev)
{
if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
@@ -1045,7 +1045,6 @@ static int ni_unrestrict_performance_levels_after_switch(struct radeon_device *r
return (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) == PPSMC_Result_OK) ?
0 : -EINVAL;
}
-#endif
static void ni_stop_smc(struct radeon_device *rdev)
{
@@ -3832,14 +3831,11 @@ int ni_dpm_set_power_state(struct radeon_device *rdev)
return ret;
}
-#if 0
- /* XXX */
ret = ni_unrestrict_performance_levels_after_switch(rdev);
if (ret) {
DRM_ERROR("ni_unrestrict_performance_levels_after_switch failed\n");
return ret;
}
-#endif
return 0;
}
@@ -4292,6 +4288,26 @@ void ni_dpm_print_power_state(struct radeon_device *rdev,
r600_dpm_print_ps_status(rdev, rps);
}
+void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m)
+{
+ struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+ struct ni_ps *ps = ni_get_ps(rps);
+ struct rv7xx_pl *pl;
+ u32 current_index =
+ (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
+ CURRENT_STATE_INDEX_SHIFT;
+
+ if (current_index >= ps->performance_level_count) {
+ seq_printf(m, "invalid dpm profile %d\n", current_index);
+ } else {
+ pl = &ps->performance_levels[current_index];
+ seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+ seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u\n",
+ current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+ }
+}
+
u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low)
{
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 95693c77351d..fe24a93542ec 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -618,6 +618,10 @@
# define MRDCKD0_BYPASS (1 << 30)
# define MRDCKD1_BYPASS (1 << 31)
+#define TARGET_AND_CURRENT_PROFILE_INDEX 0x66c
+# define CURRENT_STATE_INDEX_MASK (0xf << 4)
+# define CURRENT_STATE_INDEX_SHIFT 4
+
#define CG_AT 0x6d4
# define CG_R(x) ((x) << 0)
# define CG_R_MASK (0xffff << 0)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 7e3fef4e6938..f51807f04f65 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1667,6 +1667,7 @@ struct radeon_asic {
u32 (*get_sclk)(struct radeon_device *rdev, bool low);
u32 (*get_mclk)(struct radeon_device *rdev, bool low);
void (*print_power_state)(struct radeon_device *rdev, struct radeon_ps *ps);
+ void (*debugfs_print_current_performance_level)(struct radeon_device *rdev, struct seq_file *m);
} dpm;
/* pageflipping */
struct {
@@ -2433,6 +2434,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
#define radeon_dpm_get_sclk(rdev, l) rdev->asic->dpm.get_sclk((rdev), (l))
#define radeon_dpm_get_mclk(rdev, l) rdev->asic->dpm.get_mclk((rdev), (l))
#define radeon_dpm_print_power_state(rdev, ps) rdev->asic->dpm.print_power_state((rdev), (ps))
+#define radeon_dpm_debugfs_print_current_performance_level(rdev, m) rdev->asic->dpm.debugfs_print_current_performance_level((rdev), (m))
/* Common functions */
/* AGP */
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index c3df589715a0..a5b244dc50ca 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1160,6 +1160,7 @@ static struct radeon_asic rv6xx_asic = {
.get_sclk = &rv6xx_dpm_get_sclk,
.get_mclk = &rv6xx_dpm_get_mclk,
.print_power_state = &rv6xx_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &rv6xx_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &rs600_pre_page_flip,
@@ -1391,6 +1392,7 @@ static struct radeon_asic rv770_asic = {
.get_sclk = &rv770_dpm_get_sclk,
.get_mclk = &rv770_dpm_get_mclk,
.print_power_state = &rv770_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &rs600_pre_page_flip,
@@ -1513,6 +1515,7 @@ static struct radeon_asic evergreen_asic = {
.get_sclk = &rv770_dpm_get_sclk,
.get_mclk = &rv770_dpm_get_mclk,
.print_power_state = &rv770_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &evergreen_pre_page_flip,
@@ -1635,6 +1638,7 @@ static struct radeon_asic sumo_asic = {
.get_sclk = &sumo_dpm_get_sclk,
.get_mclk = &sumo_dpm_get_mclk,
.print_power_state = &sumo_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &sumo_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &evergreen_pre_page_flip,
@@ -1757,6 +1761,7 @@ static struct radeon_asic btc_asic = {
.get_sclk = &btc_dpm_get_sclk,
.get_mclk = &btc_dpm_get_mclk,
.print_power_state = &rv770_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &evergreen_pre_page_flip,
@@ -1931,6 +1936,7 @@ static struct radeon_asic cayman_asic = {
.get_sclk = &ni_dpm_get_sclk,
.get_mclk = &ni_dpm_get_mclk,
.print_power_state = &ni_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &ni_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &evergreen_pre_page_flip,
@@ -2103,6 +2109,7 @@ static struct radeon_asic trinity_asic = {
.get_sclk = &trinity_dpm_get_sclk,
.get_mclk = &trinity_dpm_get_mclk,
.print_power_state = &trinity_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &trinity_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &evergreen_pre_page_flip,
@@ -2275,6 +2282,7 @@ static struct radeon_asic si_asic = {
.get_sclk = &ni_dpm_get_sclk,
.get_mclk = &ni_dpm_get_mclk,
.print_power_state = &ni_dpm_print_power_state,
+ .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level,
},
.pflip = {
.pre_page_flip = &evergreen_pre_page_flip,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 2497d0a02de5..6822c7aeacaa 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -416,6 +416,8 @@ u32 rv6xx_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 rv6xx_dpm_get_mclk(struct radeon_device *rdev, bool low);
void rv6xx_dpm_print_power_state(struct radeon_device *rdev,
struct radeon_ps *ps);
+void rv6xx_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m);
/* rs780 dpm */
int rs780_dpm_init(struct radeon_device *rdev);
int rs780_dpm_enable(struct radeon_device *rdev);
@@ -474,6 +476,8 @@ u32 rv770_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low);
void rv770_dpm_print_power_state(struct radeon_device *rdev,
struct radeon_ps *ps);
+void rv770_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m);
/*
* evergreen
@@ -561,6 +565,8 @@ u32 sumo_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 sumo_dpm_get_mclk(struct radeon_device *rdev, bool low);
void sumo_dpm_print_power_state(struct radeon_device *rdev,
struct radeon_ps *ps);
+void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m);
/*
* cayman
@@ -607,6 +613,8 @@ u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 ni_dpm_get_mclk(struct radeon_device *rdev, bool low);
void ni_dpm_print_power_state(struct radeon_device *rdev,
struct radeon_ps *ps);
+void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m);
int trinity_dpm_init(struct radeon_device *rdev);
int trinity_dpm_enable(struct radeon_device *rdev);
void trinity_dpm_disable(struct radeon_device *rdev);
@@ -620,6 +628,8 @@ u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low);
void trinity_dpm_print_power_state(struct radeon_device *rdev,
struct radeon_ps *ps);
+void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m);
/* DCE6 - SI */
void dce6_bandwidth_update(struct radeon_device *rdev);
@@ -667,6 +677,8 @@ int si_dpm_set_power_state(struct radeon_device *rdev);
void si_dpm_post_set_power_state(struct radeon_device *rdev);
void si_dpm_fini(struct radeon_device *rdev);
void si_dpm_display_configuration_changed(struct radeon_device *rdev);
+void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m);
/* DCE8 - CIK */
void dce8_bandwidth_update(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index a8296e0f8543..b1777d10d0b5 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -3639,7 +3639,7 @@ int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,
p = (u8 *)vram_module->asMemTiming;
for (i = 0; i < mclk_range_table->num_entries; i++) {
format = (ATOM_MEMORY_TIMING_FORMAT *)p;
- mclk_range_table->mclk[i] = format->ulClkRange;
+ mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange);
p += mem_timing_size;
}
} else
@@ -3732,7 +3732,8 @@ int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,
}
num_ranges++;
}
- reg_data += reg_block->usRegDataBlkSize;
+ reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
+ ((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize));
}
if (*(u32 *)reg_data != END_OF_REG_DATA_BLOCK)
return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 9737baeb711d..ebbdb477745a 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1062,6 +1062,11 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
ret = device_create_file(rdev->dev, &dev_attr_power_method);
if (ret)
DRM_ERROR("failed to create device file for power method\n");
+
+ if (radeon_debugfs_pm_init(rdev)) {
+ DRM_ERROR("Failed to register debugfs file for dpm!\n");
+ }
+
DRM_INFO("radeon: dpm initialized\n");
}
@@ -1389,19 +1394,28 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private;
- seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk);
- /* radeon_get_engine_clock is not reliable on APUs so just print the current clock */
- if ((rdev->family >= CHIP_PALM) && (rdev->flags & RADEON_IS_IGP))
- seq_printf(m, "current engine clock: %u0 kHz\n", rdev->pm.current_sclk);
- else
- seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
- seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk);
- if (rdev->asic->pm.get_memory_clock)
- seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
- if (rdev->pm.current_vddc)
- seq_printf(m, "voltage: %u mV\n", rdev->pm.current_vddc);
- if (rdev->asic->pm.get_pcie_lanes)
- seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev));
+ if (rdev->pm.dpm_enabled) {
+ mutex_lock(&rdev->pm.mutex);
+ if (rdev->asic->dpm.debugfs_print_current_performance_level)
+ radeon_dpm_debugfs_print_current_performance_level(rdev, m);
+ else
+ seq_printf(m, "Debugfs support not implemented for this asic\n");
+ mutex_unlock(&rdev->pm.mutex);
+ } else {
+ seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk);
+ /* radeon_get_engine_clock is not reliable on APUs so just print the current clock */
+ if ((rdev->family >= CHIP_PALM) && (rdev->flags & RADEON_IS_IGP))
+ seq_printf(m, "current engine clock: %u0 kHz\n", rdev->pm.current_sclk);
+ else
+ seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
+ seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk);
+ if (rdev->asic->pm.get_memory_clock)
+ seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
+ if (rdev->pm.current_vddc)
+ seq_printf(m, "voltage: %u mV\n", rdev->pm.current_vddc);
+ if (rdev->asic->pm.get_pcie_lanes)
+ seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev));
+ }
return 0;
}
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c
index 0e8b7d9b954b..8303de267ee5 100644
--- a/drivers/gpu/drm/radeon/rv6xx_dpm.c
+++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c
@@ -28,6 +28,7 @@
#include "r600_dpm.h"
#include "rv6xx_dpm.h"
#include "atom.h"
+#include <linux/seq_file.h>
static u32 rv6xx_scale_count_given_unit(struct radeon_device *rdev,
u32 unscaled_count, u32 unit);
@@ -2027,6 +2028,31 @@ void rv6xx_dpm_print_power_state(struct radeon_device *rdev,
r600_dpm_print_ps_status(rdev, rps);
}
+void rv6xx_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m)
+{
+ struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+ struct rv6xx_ps *ps = rv6xx_get_ps(rps);
+ struct rv6xx_pl *pl;
+ u32 current_index =
+ (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
+ CURRENT_PROFILE_INDEX_SHIFT;
+
+ if (current_index > 2) {
+ seq_printf(m, "invalid dpm profile %d\n", current_index);
+ } else {
+ if (current_index == 0)
+ pl = &ps->low;
+ else if (current_index == 1)
+ pl = &ps->medium;
+ else /* current_index == 2 */
+ pl = &ps->high;
+ seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+ seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u\n",
+ current_index, pl->sclk, pl->mclk, pl->vddc);
+ }
+}
+
void rv6xx_dpm_fini(struct radeon_device *rdev)
{
int i;
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c
index 7f6fa6221234..9af464d48eaa 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -29,6 +29,7 @@
#include "rv770_dpm.h"
#include "cypress_dpm.h"
#include "atom.h"
+#include <linux/seq_file.h>
#define MC_CG_ARB_FREQ_F0 0x0a
#define MC_CG_ARB_FREQ_F1 0x0b
@@ -2430,6 +2431,36 @@ void rv770_dpm_print_power_state(struct radeon_device *rdev,
r600_dpm_print_ps_status(rdev, rps);
}
+void rv770_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m)
+{
+ struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+ struct rv7xx_ps *ps = rv770_get_ps(rps);
+ struct rv7xx_pl *pl;
+ u32 current_index =
+ (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
+ CURRENT_PROFILE_INDEX_SHIFT;
+
+ if (current_index > 2) {
+ seq_printf(m, "invalid dpm profile %d\n", current_index);
+ } else {
+ if (current_index == 0)
+ pl = &ps->low;
+ else if (current_index == 1)
+ pl = &ps->medium;
+ else /* current_index == 2 */
+ pl = &ps->high;
+ seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+ if (rdev->family >= CHIP_CEDAR) {
+ seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u\n",
+ current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+ } else {
+ seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u\n",
+ current_index, pl->sclk, pl->mclk, pl->vddc);
+ }
+ }
+}
+
void rv770_dpm_fini(struct radeon_device *rdev)
{
int i;
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
index 784eeaf315c3..6bef2b7d601b 100644
--- a/drivers/gpu/drm/radeon/rv770d.h
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -207,6 +207,10 @@
# define MUX_TCLK_TO_XCLK (1 << 8)
# define XTALIN_DIVIDE (1 << 9)
+#define TARGET_AND_CURRENT_PROFILE_INDEX 0x66c
+# define CURRENT_PROFILE_INDEX_MASK (0xf << 4)
+# define CURRENT_PROFILE_INDEX_SHIFT 4
+
#define S0_VID_LOWER_SMIO_CNTL 0x678
#define S1_VID_LOWER_SMIO_CNTL 0x67c
#define S2_VID_LOWER_SMIO_CNTL 0x680
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 6918f070eb52..a7e97cd05e96 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -28,6 +28,7 @@
#include "si_dpm.h"
#include "atom.h"
#include <linux/math64.h>
+#include <linux/seq_file.h>
#define MC_CG_ARB_FREQ_F0 0x0a
#define MC_CG_ARB_FREQ_F1 0x0b
@@ -6385,3 +6386,22 @@ void si_dpm_fini(struct radeon_device *rdev)
r600_free_extended_power_table(rdev);
}
+void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m)
+{
+ struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+ struct ni_ps *ps = ni_get_ps(rps);
+ struct rv7xx_pl *pl;
+ u32 current_index =
+ (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
+ CURRENT_STATE_INDEX_SHIFT;
+
+ if (current_index >= ps->performance_level_count) {
+ seq_printf(m, "invalid dpm profile %d\n", current_index);
+ } else {
+ pl = &ps->performance_levels[current_index];
+ seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+ seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",
+ current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);
+ }
+}
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index 299d657d0168..12a20eb77d0c 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -220,6 +220,10 @@
# define GFX_CLK_OFF_ACPI_D3 (1 << 13)
# define DYN_LIGHT_SLEEP_EN (1 << 14)
+#define TARGET_AND_CURRENT_PROFILE_INDEX 0x798
+# define CURRENT_STATE_INDEX_MASK (0xf << 4)
+# define CURRENT_STATE_INDEX_SHIFT 4
+
#define CG_FTV 0x7bc
#define CG_FFCT_0 0x7c0
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c
index dbad293bfed5..dc599060a9a4 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -27,6 +27,7 @@
#include "r600_dpm.h"
#include "cypress_dpm.h"
#include "sumo_dpm.h"
+#include <linux/seq_file.h>
#define SUMO_MAX_DEEPSLEEP_DIVIDER_ID 5
#define SUMO_MINIMUM_ENGINE_CLOCK 800
@@ -810,6 +811,25 @@ static void sumo_program_bootup_state(struct radeon_device *rdev)
sumo_power_level_enable(rdev, i, false);
}
+static void sumo_setup_uvd_clocks(struct radeon_device *rdev,
+ struct radeon_ps *new_rps,
+ struct radeon_ps *old_rps)
+{
+ struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+ if (pi->enable_gfx_power_gating) {
+ sumo_gfx_powergating_enable(rdev, false);
+ }
+
+ radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
+
+ if (pi->enable_gfx_power_gating) {
+ if (!pi->disable_gfx_power_gating_in_uvd ||
+ !r600_is_uvd_state(new_rps->class, new_rps->class2))
+ sumo_gfx_powergating_enable(rdev, true);
+ }
+}
+
static void sumo_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
struct radeon_ps *new_rps,
struct radeon_ps *old_rps)
@@ -825,7 +845,7 @@ static void sumo_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
current_ps->levels[current_ps->num_levels - 1].sclk)
return;
- radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
+ sumo_setup_uvd_clocks(rdev, new_rps, old_rps);
}
static void sumo_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
@@ -843,7 +863,7 @@ static void sumo_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
current_ps->levels[current_ps->num_levels - 1].sclk)
return;
- radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
+ sumo_setup_uvd_clocks(rdev, new_rps, old_rps);
}
void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
@@ -1133,22 +1153,6 @@ static void sumo_cleanup_asic(struct radeon_device *rdev)
sumo_take_smu_control(rdev, false);
}
-static void sumo_uvd_init(struct radeon_device *rdev)
-{
- u32 tmp;
-
- tmp = RREG32(CG_VCLK_CNTL);
- tmp &= ~VCLK_DIR_CNTL_EN;
- WREG32(CG_VCLK_CNTL, tmp);
-
- tmp = RREG32(CG_DCLK_CNTL);
- tmp &= ~DCLK_DIR_CNTL_EN;
- WREG32(CG_DCLK_CNTL, tmp);
-
- /* 100 Mhz */
- radeon_set_uvd_clocks(rdev, 10000, 10000);
-}
-
static int sumo_set_thermal_temperature_range(struct radeon_device *rdev,
int min_temp, int max_temp)
{
@@ -1348,7 +1352,6 @@ void sumo_dpm_setup_asic(struct radeon_device *rdev)
sumo_program_acpi_power_level(rdev);
sumo_enable_acpi_pm(rdev);
sumo_take_smu_control(rdev, true);
- sumo_uvd_init(rdev);
}
void sumo_dpm_display_configuration_changed(struct radeon_device *rdev)
@@ -1769,6 +1772,34 @@ void sumo_dpm_print_power_state(struct radeon_device *rdev,
r600_dpm_print_ps_status(rdev, rps);
}
+void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m)
+{
+ struct sumo_power_info *pi = sumo_get_pi(rdev);
+ struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+ struct sumo_ps *ps = sumo_get_ps(rps);
+ struct sumo_pl *pl;
+ u32 current_index =
+ (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_INDEX_MASK) >>
+ CURR_INDEX_SHIFT;
+
+ if (current_index == BOOST_DPM_LEVEL) {
+ pl = &pi->boost_pl;
+ seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+ seq_printf(m, "power level %d sclk: %u vddc: %u\n",
+ current_index, pl->sclk,
+ sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
+ } else if (current_index >= ps->num_levels) {
+ seq_printf(m, "invalid dpm profile %d\n", current_index);
+ } else {
+ pl = &ps->levels[current_index];
+ seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+ seq_printf(m, "power level %d sclk: %u vddc: %u\n",
+ current_index, pl->sclk,
+ sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
+ }
+}
+
void sumo_dpm_fini(struct radeon_device *rdev)
{
int i;
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c
index fce825e112ff..8a32bcc6bbb5 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -26,6 +26,7 @@
#include "trinityd.h"
#include "r600_dpm.h"
#include "trinity_dpm.h"
+#include <linux/seq_file.h>
#define TRINITY_MAX_DEEPSLEEP_DIVIDER_ID 5
#define TRINITY_MINIMUM_ENGINE_CLOCK 800
@@ -920,6 +921,10 @@ static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
{
struct trinity_power_info *pi = trinity_get_pi(rdev);
+ if (pi->enable_gfx_power_gating) {
+ trinity_gfx_powergating_enable(rdev, false);
+ }
+
if (pi->uvd_dpm) {
if (trinity_uvd_clocks_zero(new_rps) &&
!trinity_uvd_clocks_zero(old_rps)) {
@@ -945,6 +950,10 @@ static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
}
+
+ if (pi->enable_gfx_power_gating) {
+ trinity_gfx_powergating_enable(rdev, true);
+ }
}
static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
@@ -1855,6 +1864,27 @@ void trinity_dpm_print_power_state(struct radeon_device *rdev,
r600_dpm_print_ps_status(rdev, rps);
}
+void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+ struct seq_file *m)
+{
+ struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+ struct trinity_ps *ps = trinity_get_ps(rps);
+ struct trinity_pl *pl;
+ u32 current_index =
+ (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
+ CURRENT_STATE_SHIFT;
+
+ if (current_index >= ps->num_levels) {
+ seq_printf(m, "invalid dpm profile %d\n", current_index);
+ } else {
+ pl = &ps->levels[current_index];
+ seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+ seq_printf(m, "power level %d sclk: %u vddc: %u\n",
+ current_index, pl->sclk,
+ trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
+ }
+}
+
void trinity_dpm_fini(struct radeon_device *rdev)
{
int i;
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 6e6975c8596f..cb9dd674670c 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1455,9 +1455,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev,
goto out_no_sys;
bdev->addr_space_rb = RB_ROOT;
- ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
- if (unlikely(ret != 0))
- goto out_no_addr_mm;
+ drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
INIT_LIST_HEAD(&bdev->ddestroy);
@@ -1471,8 +1469,6 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev,
mutex_unlock(&glob->device_list_mutex);
return 0;
-out_no_addr_mm:
- ttm_bo_clean_mm(bdev, 0);
out_no_sys:
return ret;
}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c
index 9212494e9072..e4367f91472a 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c
@@ -103,18 +103,12 @@ static int ttm_bo_man_init(struct ttm_mem_type_manager *man,
unsigned long p_size)
{
struct ttm_range_manager *rman;
- int ret;
rman = kzalloc(sizeof(*rman), GFP_KERNEL);
if (!rman)
return -ENOMEM;
- ret = drm_mm_init(&rman->mm, 0, p_size);
- if (ret) {
- kfree(rman);
- return ret;
- }
-
+ drm_mm_init(&rman->mm, 0, p_size);
spin_lock_init(&rman->lock);
man->priv = rman;
return 0;
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 88591ef8fa24..de9242542f05 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -275,9 +275,9 @@ static inline struct drm_mm_node *drm_mm_search_free_in_range_color(
return drm_mm_search_free_in_range_generic(mm, size, alignment, color,
start, end, best_match);
}
-extern int drm_mm_init(struct drm_mm *mm,
- unsigned long start,
- unsigned long size);
+extern void drm_mm_init(struct drm_mm *mm,
+ unsigned long start,
+ unsigned long size);
extern void drm_mm_takedown(struct drm_mm *mm);
extern int drm_mm_clean(struct drm_mm *mm);
extern int drm_mm_pre_get(struct drm_mm *mm);