summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/gpu
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/Kconfig73
-rw-r--r--drivers/gpu/drm/Makefile5
-rw-r--r--drivers/gpu/drm/armada/Kconfig24
-rw-r--r--drivers/gpu/drm/armada/Makefile7
-rw-r--r--drivers/gpu/drm/armada/armada_510.c87
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c1098
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.h83
-rw-r--r--drivers/gpu/drm/armada/armada_debugfs.c177
-rw-r--r--drivers/gpu/drm/armada/armada_drm.h113
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c421
-rw-r--r--drivers/gpu/drm/armada/armada_fb.c170
-rw-r--r--drivers/gpu/drm/armada/armada_fb.h24
-rw-r--r--drivers/gpu/drm/armada/armada_fbdev.c202
-rw-r--r--drivers/gpu/drm/armada/armada_gem.c611
-rw-r--r--drivers/gpu/drm/armada/armada_gem.h52
-rw-r--r--drivers/gpu/drm/armada/armada_hw.h318
-rw-r--r--drivers/gpu/drm/armada/armada_ioctlP.h18
-rw-r--r--drivers/gpu/drm/armada/armada_output.c158
-rw-r--r--drivers/gpu/drm/armada/armada_output.h39
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c477
-rw-r--r--drivers/gpu/drm/armada/armada_slave.c139
-rw-r--r--drivers/gpu/drm/armada/armada_slave.h26
-rw-r--r--drivers/gpu/drm/ast/Kconfig1
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c1
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h1
-rw-r--r--drivers/gpu/drm/ast/ast_main.c6
-rw-r--r--drivers/gpu/drm/cirrus/Kconfig1
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c1
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.h1
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_main.c6
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c11
-rw-r--r--drivers/gpu/drm/drm_context.c2
-rw-r--r--drivers/gpu/drm/drm_crtc.c153
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c96
-rw-r--r--drivers/gpu/drm/drm_debugfs.c6
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c16
-rw-r--r--drivers/gpu/drm/drm_drv.c74
-rw-r--r--drivers/gpu/drm/drm_edid.c314
-rw-r--r--drivers/gpu/drm/drm_edid_load.c108
-rw-r--r--drivers/gpu/drm/drm_encoder_slave.c8
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c17
-rw-r--r--drivers/gpu/drm/drm_flip_work.c2
-rw-r--r--drivers/gpu/drm/drm_fops.c94
-rw-r--r--drivers/gpu/drm/drm_gem.c29
-rw-r--r--drivers/gpu/drm/drm_global.c2
-rw-r--r--drivers/gpu/drm/drm_info.c6
-rw-r--r--drivers/gpu/drm/drm_ioctl.c21
-rw-r--r--drivers/gpu/drm/drm_irq.c181
-rw-r--r--drivers/gpu/drm/drm_lock.c3
-rw-r--r--drivers/gpu/drm/drm_modes.c43
-rw-r--r--drivers/gpu/drm/drm_pci.c69
-rw-r--r--drivers/gpu/drm/drm_platform.c59
-rw-r--r--drivers/gpu/drm/drm_prime.c3
-rw-r--r--drivers/gpu/drm/drm_stub.c362
-rw-r--r--drivers/gpu/drm/drm_sysfs.c118
-rw-r--r--drivers/gpu/drm/drm_usb.c57
-rw-r--r--drivers/gpu/drm/drm_vm.c2
-rw-r--r--drivers/gpu/drm/exynos/Kconfig1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c42
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_g2d.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c16
-rw-r--r--drivers/gpu/drm/gma500/Kconfig1
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c1
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c2
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c2
-rw-r--r--drivers/gpu/drm/gma500/gem.c5
-rw-r--r--drivers/gpu/drm/gma500/intel_gmbus.c90
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.h2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_crtc.c433
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c8
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c32
-rw-r--r--drivers/gpu/drm/gma500/psb_device.c1
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c39
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h58
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c59
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.c22
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c3
-rw-r--r--drivers/gpu/drm/i810/i810_dma.c11
-rw-r--r--drivers/gpu/drm/i915/Kconfig67
-rw-r--r--drivers/gpu/drm/i915/Makefile6
-rw-r--r--drivers/gpu/drm/i915/dvo.h11
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c1205
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c118
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c189
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h438
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c557
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c64
-rw-r--r--drivers/gpu/drm/i915/i915_gem_dmabuf.c13
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c50
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c443
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c514
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c8
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c46
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c1043
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h828
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c44
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c152
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h62
-rw-r--r--drivers/gpu/drm/i915/intel_acpi.c8
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c202
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h121
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c29
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c274
-rw-r--r--drivers/gpu/drm/i915/intel_display.c1748
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c779
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h565
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.c620
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.h102
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_cmd.c427
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_cmd.h109
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_pll.c317
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c28
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c (renamed from drivers/gpu/drm/i915/intel_fbdev.c)33
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c83
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c64
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c25
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c496
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c9
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c346
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c1341
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c275
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h15
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c52
-rw-r--r--drivers/gpu/drm/i915/intel_sideband.c79
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c203
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c29
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c449
-rw-r--r--drivers/gpu/drm/mga/mga_dma.c5
-rw-r--r--drivers/gpu/drm/mga/mga_irq.c2
-rw-r--r--drivers/gpu/drm/mgag200/Kconfig1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_main.c6
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c2
-rw-r--r--drivers/gpu/drm/msm/Kconfig1
-rw-r--r--drivers/gpu/drm/msm/Makefile1
-rw-r--r--drivers/gpu/drm/msm/adreno/a2xx.xml.h42
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx.xml.h46
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_common.xml.h10
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h10
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.xml.h6
-rw-r--r--drivers/gpu/drm/msm/dsi/mmss_cc.xml.h6
-rw-r--r--drivers/gpu/drm/msm/dsi/sfpb.xml.h6
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.xml.h6
-rw-r--r--drivers/gpu/drm/msm/hdmi/qfprom.xml.h6
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4.xml.h126
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_crtc.c208
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_format.c16
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_kms.c19
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_kms.h58
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_plane.c30
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c60
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h37
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c160
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h3
-rw-r--r--drivers/gpu/drm/msm/msm_gem_prime.c56
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c4
-rw-r--r--drivers/gpu/drm/nouveau/Kconfig1
-rw-r--r--drivers/gpu/drm/nouveau/Makefile49
-rw-r--r--drivers/gpu/drm/nouveau/core/core/event.c119
-rw-r--r--drivers/gpu/drm/nouveau/core/core/option.c11
-rw-r--r--drivers/gpu/drm/nouveau/core/core/printk.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/base.c56
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/ctrl.c144
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv04.c20
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv10.c76
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv20.c40
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv30.c50
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv40.c218
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv50.c195
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nvc0.c118
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nve0.c99
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/priv.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/dport.c52
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv04.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c12
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c12
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c13
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c11
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c11
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv10.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c68
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h15
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c103
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c194
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/base.c449
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c109
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c143
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h26
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c70
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c78
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c96
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c173
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c162
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c71
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h91
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv04.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv10.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv50.c96
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv50.h47
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nvc0.c130
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/class.h73
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/debug.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/event.h22
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/option.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/printk.h30
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/fifo.h16
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/mpeg.h5
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/perfmon.h39
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/software.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h29
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h28
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h10
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h11
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h25
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h27
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bus.h20
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h115
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h50
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/i2c.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/mc.h29
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/pwr.h80
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/therm.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/volt.h60
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/boost.c127
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c123
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dp.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/perf.c140
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/pll.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c88
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/timing.c73
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c112
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/volt.c137
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c145
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h113
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c44
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c60
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c59
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/base.c494
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c183
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c520
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c48
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c271
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h14
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c445
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c404
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c497
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c37
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/seq.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/base.c15
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c96
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c29
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h55
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c53
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c50
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c50
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c48
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c46
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c48
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c48
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c51
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c39
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c39
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c39
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c39
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c33
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h29
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/priv.h53
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h118
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c168
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c15
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c344
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c447
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c66
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c567
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c1264
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h18
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c99
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/base.c27
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/base.c89
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c44
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h21
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c41
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c37
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c40
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/base.c247
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc151
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc84
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc452
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc199
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc219
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc63
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h1165
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc63
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h1229
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc63
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h1229
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc63
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h1229
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h27
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc57
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc64
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c121
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c62
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c71
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c62
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c62
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/base.c55
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/fan.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/ic.c57
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/priv.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/temp.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/volt/base.c198
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c96
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c56
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/Makefile1
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/arb.c8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/dfp.c22
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/disp.c2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/disp.h9
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/hw.c16
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/overlay.c340
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvnv04.c22
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c23
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_agp.c44
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c25
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c21
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c188
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.h7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c121
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.h15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c45
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c30
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c51
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hwmon.h43
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hwsq.h115
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c647
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_perf.c416
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c (renamed from drivers/gpu/drm/nouveau/nouveau_hwmon.c)559
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.h283
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_prime.c10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sysfs.c162
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sysfs.h19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_volt.c250
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fbcon.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv04_pm.c146
-rw-r--r--drivers/gpu/drm/nouveau/nv40_pm.c353
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c855
-rw-r--r--drivers/gpu/drm/nouveau/nva3_pm.c624
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_pm.c599
-rw-r--r--drivers/gpu/drm/omapdrm/Kconfig1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_dmm_tiler.c5
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c5
-rw-r--r--drivers/gpu/drm/omapdrm/omap_irq.c17
-rw-r--r--drivers/gpu/drm/qxl/Kconfig1
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c51
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c1
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h3
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_gem.c6
-rw-r--r--drivers/gpu/drm/qxl/qxl_kms.c42
-rw-r--r--drivers/gpu/drm/qxl/qxl_release.c1
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c2
-rw-r--r--drivers/gpu/drm/radeon/atombios.h127
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c21
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c3
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c26
-rw-r--r--drivers/gpu/drm/radeon/atombios_i2c.c17
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.c58
-rw-r--r--drivers/gpu/drm/radeon/ci_smc.c4
-rw-r--r--drivers/gpu/drm/radeon/cik.c800
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c75
-rw-r--r--drivers/gpu/drm/radeon/cikd.h103
-rw-r--r--drivers/gpu/drm/radeon/cypress_dpm.c2
-rw-r--r--drivers/gpu/drm/radeon/dce6_afmt.c76
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c97
-rw-r--r--drivers/gpu/drm/radeon/evergreen_dma.c9
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c71
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h70
-rw-r--r--drivers/gpu/drm/radeon/ni.c76
-rw-r--r--drivers/gpu/drm/radeon/ni_dma.c19
-rw-r--r--drivers/gpu/drm/radeon/ni_dpm.c30
-rw-r--r--drivers/gpu/drm/radeon/r100.c5
-rw-r--r--drivers/gpu/drm/radeon/r600.c66
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c18
-rw-r--r--drivers/gpu/drm/radeon/r600_dma.c13
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c110
-rw-r--r--drivers/gpu/drm/radeon/r600d.h28
-rw-r--r--drivers/gpu/drm/radeon/radeon.h79
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c78
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h53
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c116
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c311
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c125
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c83
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c176
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_family.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c380
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c93
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_ioc32.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c39
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c49
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h17
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c112
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c46
-rw-r--r--drivers/gpu/drm/radeon/radeon_semaphore.c129
-rw-r--r--drivers/gpu/drm/radeon/radeon_trace.h93
-rw-r--r--drivers/gpu/drm/radeon/radeon_ucode.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_uvd.c5
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/cayman4
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/evergreen4
-rw-r--r--drivers/gpu/drm/radeon/rs600.c64
-rw-r--r--drivers/gpu/drm/radeon/rs690.c16
-rw-r--r--drivers/gpu/drm/radeon/rv515.c8
-rw-r--r--drivers/gpu/drm/radeon/rv6xx_dpm.c6
-rw-r--r--drivers/gpu/drm/radeon/rv770_dma.c9
-rw-r--r--drivers/gpu/drm/radeon/si.c110
-rw-r--r--drivers/gpu/drm/radeon/si_dma.c31
-rw-r--r--drivers/gpu/drm/radeon/si_dpm.c9
-rw-r--r--drivers/gpu/drm/radeon/sid.h47
-rw-r--r--drivers/gpu/drm/radeon/trinity_dpm.c6
-rw-r--r--drivers/gpu/drm/radeon/uvd_v1_0.c4
-rw-r--r--drivers/gpu/drm/radeon/uvd_v3_1.c4
-rw-r--r--drivers/gpu/drm/rcar-du/Kconfig1
-rw-r--r--drivers/gpu/drm/shmobile/Kconfig2
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_crtc.c4
-rw-r--r--drivers/gpu/drm/tegra/Makefile15
-rw-r--r--drivers/gpu/drm/tegra/bus.c76
-rw-r--r--drivers/gpu/drm/tegra/drm.c718
-rw-r--r--drivers/gpu/drm/tegra/gr2d.c227
-rw-r--r--drivers/gpu/drm/tegra/gr2d.h28
-rw-r--r--drivers/gpu/drm/tegra/gr3d.c338
-rw-r--r--drivers/gpu/drm/tegra/gr3d.h27
-rw-r--r--drivers/gpu/drm/tilcdc/Kconfig1
-rw-r--r--drivers/gpu/drm/ttm/Makefile6
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c81
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c35
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_vm.c118
-rw-r--r--drivers/gpu/drm/ttm/ttm_execbuf_util.c32
-rw-r--r--drivers/gpu/drm/ttm/ttm_object.c254
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc_dma.c3
-rw-r--r--drivers/gpu/drm/udl/Kconfig1
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c1
-rw-r--r--drivers/gpu/drm/udl/udl_drv.h1
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c13
-rw-r--r--drivers/gpu/drm/via/via_mm.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/Makefile2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c381
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c101
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h113
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c153
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c3
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_prime.c137
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c203
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_surface.c30
-rw-r--r--drivers/gpu/host1x/Kconfig2
-rw-r--r--drivers/gpu/host1x/Makefile13
-rw-r--r--drivers/gpu/host1x/bus.c551
-rw-r--r--drivers/gpu/host1x/cdma.c2
-rw-r--r--drivers/gpu/host1x/channel.h6
-rw-r--r--drivers/gpu/host1x/dev.c82
-rw-r--r--drivers/gpu/host1x/dev.h11
-rw-r--r--drivers/gpu/host1x/drm/Kconfig (renamed from drivers/gpu/drm/tegra/Kconfig)13
-rw-r--r--drivers/gpu/host1x/drm/dc.c (renamed from drivers/gpu/drm/tegra/dc.c)108
-rw-r--r--drivers/gpu/host1x/drm/dc.h (renamed from drivers/gpu/drm/tegra/dc.h)5
-rw-r--r--drivers/gpu/host1x/drm/drm.c647
-rw-r--r--drivers/gpu/host1x/drm/drm.h (renamed from drivers/gpu/drm/tegra/drm.h)103
-rw-r--r--drivers/gpu/host1x/drm/fb.c (renamed from drivers/gpu/drm/tegra/fb.c)40
-rw-r--r--drivers/gpu/host1x/drm/gem.c (renamed from drivers/gpu/drm/tegra/gem.c)44
-rw-r--r--drivers/gpu/host1x/drm/gem.h (renamed from drivers/gpu/drm/tegra/gem.h)16
-rw-r--r--drivers/gpu/host1x/drm/gr2d.c343
-rw-r--r--drivers/gpu/host1x/drm/hdmi.c (renamed from drivers/gpu/drm/tegra/hdmi.c)257
-rw-r--r--drivers/gpu/host1x/drm/hdmi.h (renamed from drivers/gpu/drm/tegra/hdmi.h)152
-rw-r--r--drivers/gpu/host1x/drm/output.c (renamed from drivers/gpu/drm/tegra/output.c)64
-rw-r--r--drivers/gpu/host1x/drm/rgb.c (renamed from drivers/gpu/drm/tegra/rgb.c)30
-rw-r--r--drivers/gpu/host1x/host1x.h30
-rw-r--r--drivers/gpu/host1x/host1x_bo.h87
-rw-r--r--drivers/gpu/host1x/host1x_client.h (renamed from drivers/gpu/host1x/bus.h)24
-rw-r--r--drivers/gpu/host1x/hw/Makefile6
-rw-r--r--drivers/gpu/host1x/hw/cdma_hw.c12
-rw-r--r--drivers/gpu/host1x/hw/channel_hw.c32
-rw-r--r--drivers/gpu/host1x/hw/debug_hw.c20
-rw-r--r--drivers/gpu/host1x/hw/host1x01.c16
-rw-r--r--drivers/gpu/host1x/hw/host1x02.c42
-rw-r--r--drivers/gpu/host1x/hw/host1x02.h26
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x01_uclass.h6
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x02_channel.h121
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x02_sync.h243
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x02_uclass.h175
-rw-r--r--drivers/gpu/host1x/hw/intr_hw.c4
-rw-r--r--drivers/gpu/host1x/hw/syncpt_hw.c4
-rw-r--r--drivers/gpu/host1x/job.c73
-rw-r--r--drivers/gpu/host1x/job.h108
-rw-r--r--drivers/gpu/host1x/syncpt.c92
-rw-r--r--drivers/gpu/host1x/syncpt.h46
571 files changed, 15274 insertions, 45744 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f864275..955555d 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -29,17 +29,11 @@ config DRM_USB
config DRM_KMS_HELPER
tristate
depends on DRM
- help
- CRTC helpers for KMS drivers.
-
-config DRM_KMS_FB_HELPER
- bool
- depends on DRM_KMS_HELPER
select FB
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
help
- FBDEV helpers for KMS drivers.
+ FB and CRTC helpers for KMS drivers.
config DRM_LOAD_EDID_FIRMWARE
bool "Allow to specify an EDID data set instead of probing for it"
@@ -70,7 +64,6 @@ config DRM_GEM_CMA_HELPER
config DRM_KMS_CMA_HELPER
bool
select DRM_GEM_CMA_HELPER
- select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
@@ -103,7 +96,6 @@ config DRM_RADEON
select FB_CFB_IMAGEBLIT
select FW_LOADER
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_TTM
select POWER_SUPPLY
select HWMON
@@ -128,7 +120,64 @@ config DRM_I810
selected, the module will be called i810. AGP support is required
for this driver to work.
-source "drivers/gpu/drm/i915/Kconfig"
+config DRM_I915
+ tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics"
+ depends on DRM
+ depends on AGP
+ depends on AGP_INTEL
+ # we need shmfs for the swappable backing store, and in particular
+ # the shmem_readpage() which depends upon tmpfs
+ select SHMEM
+ select TMPFS
+ select DRM_KMS_HELPER
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ # i915 depends on ACPI_VIDEO when ACPI is enabled
+ # but for select to work, need to select ACPI_VIDEO's dependencies, ick
+ select BACKLIGHT_LCD_SUPPORT if ACPI
+ select BACKLIGHT_CLASS_DEVICE if ACPI
+ select VIDEO_OUTPUT_CONTROL if ACPI
+ select INPUT if ACPI
+ select THERMAL if ACPI
+ select ACPI_VIDEO if ACPI
+ select ACPI_BUTTON if ACPI
+ help
+ Choose this option if you have a system that has "Intel Graphics
+ Media Accelerator" or "HD Graphics" integrated graphics,
+ including 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G,
+ G35, G41, G43, G45 chipsets and Celeron, Pentium, Core i3,
+ Core i5, Core i7 as well as Atom CPUs with integrated graphics.
+ If M is selected, the module will be called i915. AGP support
+ is required for this driver to work. This driver is used by
+ the Intel driver in X.org 6.8 and XFree86 4.4 and above. It
+ replaces the older i830 module that supported a subset of the
+ hardware in older X.org releases.
+
+ Note that the older i810/i815 chipsets require the use of the
+ i810 driver instead, and the Atom z5xx series has an entirely
+ different implementation.
+
+config DRM_I915_KMS
+ bool "Enable modesetting on intel by default"
+ depends on DRM_I915
+ help
+ Choose this option if you want kernel modesetting enabled by default,
+ and you have a new enough userspace to support this. Running old
+ userspaces with this enabled will cause pain. Note that this causes
+ the driver to bind to PCI devices, which precludes loading things
+ like intelfb.
+
+config DRM_I915_PRELIMINARY_HW_SUPPORT
+ bool "Enable preliminary support for prerelease Intel hardware by default"
+ depends on DRM_I915
+ help
+ Choose this option if you have prerelease Intel hardware and want the
+ i915 driver to support it by default. You can enable such support at
+ runtime with the module option i915.preliminary_hw_support=1; this
+ option changes the default for that module option.
+
+ If in doubt, say "N".
config DRM_MGA
tristate "Matrox g200/g400"
@@ -176,8 +225,6 @@ source "drivers/gpu/drm/mgag200/Kconfig"
source "drivers/gpu/drm/cirrus/Kconfig"
-source "drivers/gpu/drm/armada/Kconfig"
-
source "drivers/gpu/drm/rcar-du/Kconfig"
source "drivers/gpu/drm/shmobile/Kconfig"
@@ -189,5 +236,3 @@ source "drivers/gpu/drm/tilcdc/Kconfig"
source "drivers/gpu/drm/qxl/Kconfig"
source "drivers/gpu/drm/msm/Kconfig"
-
-source "drivers/gpu/drm/tegra/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index cc08b84..f089adf 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -21,9 +21,8 @@ drm-$(CONFIG_PCI) += ati_pcigart.o
drm-usb-y := drm_usb.o
-drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o
+drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_helper.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
-drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
@@ -50,12 +49,10 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/
obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_UDL) += udl/
obj-$(CONFIG_DRM_AST) += ast/
-obj-$(CONFIG_DRM_ARMADA) += armada/
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
obj-$(CONFIG_DRM_OMAP) += omapdrm/
obj-$(CONFIG_DRM_TILCDC) += tilcdc/
obj-$(CONFIG_DRM_QXL) += qxl/
obj-$(CONFIG_DRM_MSM) += msm/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
obj-y += i2c/
diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig
deleted file mode 100644
index 40d3715..0000000
--- a/drivers/gpu/drm/armada/Kconfig
+++ /dev/null
@@ -1,24 +0,0 @@
-config DRM_ARMADA
- tristate "DRM support for Marvell Armada SoCs"
- depends on DRM && HAVE_CLK && ARM
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select DRM_KMS_HELPER
- help
- Support the "LCD" controllers found on the Marvell Armada 510
- devices. There are two controllers on the device, each controller
- supports graphics and video overlays.
-
- This driver provides no built-in acceleration; acceleration is
- performed by other IP found on the SoC. This driver provides
- kernel mode setting and buffer management to userspace.
-
-config DRM_ARMADA_TDA1998X
- bool "Support TDA1998X HDMI output"
- depends on DRM_ARMADA != n
- depends on I2C && DRM_I2C_NXP_TDA998X = y
- default y
- help
- Support the TDA1998x HDMI output device found on the Solid-Run
- CuBox.
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
deleted file mode 100644
index d6f43e0..0000000
--- a/drivers/gpu/drm/armada/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
- armada_gem.o armada_output.o armada_overlay.o \
- armada_slave.o
-armada-y += armada_510.o
-armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
-
-obj-$(CONFIG_DRM_ARMADA) := armada.o
diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c
deleted file mode 100644
index 59948ef..0000000
--- a/drivers/gpu/drm/armada/armada_510.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Armada 510 (aka Dove) variant support
- */
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include "armada_crtc.h"
-#include "armada_drm.h"
-#include "armada_hw.h"
-
-static int armada510_init(struct armada_private *priv, struct device *dev)
-{
- priv->extclk[0] = devm_clk_get(dev, "ext_ref_clk_1");
-
- if (IS_ERR(priv->extclk[0]) && PTR_ERR(priv->extclk[0]) == -ENOENT)
- priv->extclk[0] = ERR_PTR(-EPROBE_DEFER);
-
- return PTR_RET(priv->extclk[0]);
-}
-
-static int armada510_crtc_init(struct armada_crtc *dcrtc)
-{
- /* Lower the watermark so to eliminate jitter at higher bandwidths */
- armada_updatel(0x20, (1 << 11) | 0xff, dcrtc->base + LCD_CFG_RDREG4F);
- return 0;
-}
-
-/*
- * Armada510 specific SCLK register selection.
- * This gets called with sclk = NULL to test whether the mode is
- * supportable, and again with sclk != NULL to set the clocks up for
- * that. The former can return an error, but the latter is expected
- * not to.
- *
- * We currently are pretty rudimentary here, always selecting
- * EXT_REF_CLK_1 for LCD0 and erroring LCD1. This needs improvement!
- */
-static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
- const struct drm_display_mode *mode, uint32_t *sclk)
-{
- struct armada_private *priv = dcrtc->crtc.dev->dev_private;
- struct clk *clk = priv->extclk[0];
- int ret;
-
- if (dcrtc->num == 1)
- return -EINVAL;
-
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- if (dcrtc->clk != clk) {
- ret = clk_prepare_enable(clk);
- if (ret)
- return ret;
- dcrtc->clk = clk;
- }
-
- if (sclk) {
- uint32_t rate, ref, div;
-
- rate = mode->clock * 1000;
- ref = clk_round_rate(clk, rate);
- div = DIV_ROUND_UP(ref, rate);
- if (div < 1)
- div = 1;
-
- clk_set_rate(clk, ref);
- *sclk = div | SCLK_510_EXTCLK1;
- }
-
- return 0;
-}
-
-const struct armada_variant armada510_ops = {
- .has_spu_adv_reg = true,
- .spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
- .init = armada510_init,
- .crtc_init = armada510_crtc_init,
- .crtc_compute_clock = armada510_crtc_compute_clock,
-};
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
deleted file mode 100644
index d8e3982..0000000
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ /dev/null
@@ -1,1098 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- * Rewritten from the dovefb driver, and Armada510 manuals.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/clk.h>
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include "armada_crtc.h"
-#include "armada_drm.h"
-#include "armada_fb.h"
-#include "armada_gem.h"
-#include "armada_hw.h"
-
-struct armada_frame_work {
- struct drm_pending_vblank_event *event;
- struct armada_regs regs[4];
- struct drm_framebuffer *old_fb;
-};
-
-enum csc_mode {
- CSC_AUTO = 0,
- CSC_YUV_CCIR601 = 1,
- CSC_YUV_CCIR709 = 2,
- CSC_RGB_COMPUTER = 1,
- CSC_RGB_STUDIO = 2,
-};
-
-/*
- * A note about interlacing. Let's consider HDMI 1920x1080i.
- * The timing parameters we have from X are:
- * Hact HsyA HsyI Htot Vact VsyA VsyI Vtot
- * 1920 2448 2492 2640 1080 1084 1094 1125
- * Which get translated to:
- * Hact HsyA HsyI Htot Vact VsyA VsyI Vtot
- * 1920 2448 2492 2640 540 542 547 562
- *
- * This is how it is defined by CEA-861-D - line and pixel numbers are
- * referenced to the rising edge of VSYNC and HSYNC. Total clocks per
- * line: 2640. The odd frame, the first active line is at line 21, and
- * the even frame, the first active line is 584.
- *
- * LN: 560 561 562 563 567 568 569
- * DE: ~~~|____________________________//__________________________
- * HSYNC: ____|~|_____|~|_____|~|_____|~|_//__|~|_____|~|_____|~|_____
- * VSYNC: _________________________|~~~~~~//~~~~~~~~~~~~~~~|__________
- * 22 blanking lines. VSYNC at 1320 (referenced to the HSYNC rising edge).
- *
- * LN: 1123 1124 1125 1 5 6 7
- * DE: ~~~|____________________________//__________________________
- * HSYNC: ____|~|_____|~|_____|~|_____|~|_//__|~|_____|~|_____|~|_____
- * VSYNC: ____________________|~~~~~~~~~~~//~~~~~~~~~~|_______________
- * 23 blanking lines
- *
- * The Armada LCD Controller line and pixel numbers are, like X timings,
- * referenced to the top left of the active frame.
- *
- * So, translating these to our LCD controller:
- * Odd frame, 563 total lines, VSYNC at line 543-548, pixel 1128.
- * Even frame, 562 total lines, VSYNC at line 542-547, pixel 2448.
- * Note: Vsync front porch remains constant!
- *
- * if (odd_frame) {
- * vtotal = mode->crtc_vtotal + 1;
- * vbackporch = mode->crtc_vsync_start - mode->crtc_vdisplay + 1;
- * vhorizpos = mode->crtc_hsync_start - mode->crtc_htotal / 2
- * } else {
- * vtotal = mode->crtc_vtotal;
- * vbackporch = mode->crtc_vsync_start - mode->crtc_vdisplay;
- * vhorizpos = mode->crtc_hsync_start;
- * }
- * vfrontporch = mode->crtc_vtotal - mode->crtc_vsync_end;
- *
- * So, we need to reprogram these registers on each vsync event:
- * LCD_SPU_V_PORCH, LCD_SPU_ADV_REG, LCD_SPUT_V_H_TOTAL
- *
- * Note: we do not use the frame done interrupts because these appear
- * to happen too early, and lead to jitter on the display (presumably
- * they occur at the end of the last active line, before the vsync back
- * porch, which we're reprogramming.)
- */
-
-void
-armada_drm_crtc_update_regs(struct armada_crtc *dcrtc, struct armada_regs *regs)
-{
- while (regs->offset != ~0) {
- void __iomem *reg = dcrtc->base + regs->offset;
- uint32_t val;
-
- val = regs->mask;
- if (val != 0)
- val &= readl_relaxed(reg);
- writel_relaxed(val | regs->val, reg);
- ++regs;
- }
-}
-
-#define dpms_blanked(dpms) ((dpms) != DRM_MODE_DPMS_ON)
-
-static void armada_drm_crtc_update(struct armada_crtc *dcrtc)
-{
- uint32_t dumb_ctrl;
-
- dumb_ctrl = dcrtc->cfg_dumb_ctrl;
-
- if (!dpms_blanked(dcrtc->dpms))
- dumb_ctrl |= CFG_DUMB_ENA;
-
- /*
- * When the dumb interface isn't in DUMB24_RGB888_0 mode, it might
- * be using SPI or GPIO. If we set this to DUMB_BLANK, we will
- * force LCD_D[23:0] to output blank color, overriding the GPIO or
- * SPI usage. So leave it as-is unless in DUMB24_RGB888_0 mode.
- */
- if (dpms_blanked(dcrtc->dpms) &&
- (dumb_ctrl & DUMB_MASK) == DUMB24_RGB888_0) {
- dumb_ctrl &= ~DUMB_MASK;
- dumb_ctrl |= DUMB_BLANK;
- }
-
- /*
- * The documentation doesn't indicate what the normal state of
- * the sync signals are. Sebastian Hesselbart kindly probed
- * these signals on his board to determine their state.
- *
- * The non-inverted state of the sync signals is active high.
- * Setting these bits makes the appropriate signal active low.
- */
- if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NCSYNC)
- dumb_ctrl |= CFG_INV_CSYNC;
- if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NHSYNC)
- dumb_ctrl |= CFG_INV_HSYNC;
- if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NVSYNC)
- dumb_ctrl |= CFG_INV_VSYNC;
-
- if (dcrtc->dumb_ctrl != dumb_ctrl) {
- dcrtc->dumb_ctrl = dumb_ctrl;
- writel_relaxed(dumb_ctrl, dcrtc->base + LCD_SPU_DUMB_CTRL);
- }
-}
-
-static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
- int x, int y, struct armada_regs *regs, bool interlaced)
-{
- struct armada_gem_object *obj = drm_fb_obj(fb);
- unsigned pitch = fb->pitches[0];
- unsigned offset = y * pitch + x * fb->bits_per_pixel / 8;
- uint32_t addr_odd, addr_even;
- unsigned i = 0;
-
- DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n",
- pitch, x, y, fb->bits_per_pixel);
-
- addr_odd = addr_even = obj->dev_addr + offset;
-
- if (interlaced) {
- addr_even += pitch;
- pitch *= 2;
- }
-
- /* write offset, base, and pitch */
- armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0);
- armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1);
- armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH);
-
- return i;
-}
-
-static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
- struct armada_frame_work *work)
-{
- struct drm_device *dev = dcrtc->crtc.dev;
- unsigned long flags;
- int ret;
-
- ret = drm_vblank_get(dev, dcrtc->num);
- if (ret) {
- DRM_ERROR("failed to acquire vblank counter\n");
- return ret;
- }
-
- spin_lock_irqsave(&dev->event_lock, flags);
- if (!dcrtc->frame_work)
- dcrtc->frame_work = work;
- else
- ret = -EBUSY;
- spin_unlock_irqrestore(&dev->event_lock, flags);
-
- if (ret)
- drm_vblank_put(dev, dcrtc->num);
-
- return ret;
-}
-
-static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc)
-{
- struct drm_device *dev = dcrtc->crtc.dev;
- struct armada_frame_work *work = dcrtc->frame_work;
-
- dcrtc->frame_work = NULL;
-
- armada_drm_crtc_update_regs(dcrtc, work->regs);
-
- if (work->event)
- drm_send_vblank_event(dev, dcrtc->num, work->event);
-
- drm_vblank_put(dev, dcrtc->num);
-
- /* Finally, queue the process-half of the cleanup. */
- __armada_drm_queue_unref_work(dcrtc->crtc.dev, work->old_fb);
- kfree(work);
-}
-
-static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
- struct drm_framebuffer *fb, bool force)
-{
- struct armada_frame_work *work;
-
- if (!fb)
- return;
-
- if (force) {
- /* Display is disabled, so just drop the old fb */
- drm_framebuffer_unreference(fb);
- return;
- }
-
- work = kmalloc(sizeof(*work), GFP_KERNEL);
- if (work) {
- int i = 0;
- work->event = NULL;
- work->old_fb = fb;
- armada_reg_queue_end(work->regs, i);
-
- if (armada_drm_crtc_queue_frame_work(dcrtc, work) == 0)
- return;
-
- kfree(work);
- }
-
- /*
- * Oops - just drop the reference immediately and hope for
- * the best. The worst that will happen is the buffer gets
- * reused before it has finished being displayed.
- */
- drm_framebuffer_unreference(fb);
-}
-
-static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
-{
- struct drm_device *dev = dcrtc->crtc.dev;
-
- /*
- * Tell the DRM core that vblank IRQs aren't going to happen for
- * a while. This cleans up any pending vblank events for us.
- */
- drm_vblank_off(dev, dcrtc->num);
-
- /* Handle any pending flip event. */
- spin_lock_irq(&dev->event_lock);
- if (dcrtc->frame_work)
- armada_drm_crtc_complete_frame_work(dcrtc);
- spin_unlock_irq(&dev->event_lock);
-}
-
-void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
- int idx)
-{
-}
-
-void armada_drm_crtc_gamma_get(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
- int idx)
-{
-}
-
-/* The mode_config.mutex will be held for this call */
-static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
-{
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-
- if (dcrtc->dpms != dpms) {
- dcrtc->dpms = dpms;
- armada_drm_crtc_update(dcrtc);
- if (dpms_blanked(dpms))
- armada_drm_vblank_off(dcrtc);
- }
-}
-
-/*
- * Prepare for a mode set. Turn off overlay to ensure that we don't end
- * up with the overlay size being bigger than the active screen size.
- * We rely upon X refreshing this state after the mode set has completed.
- *
- * The mode_config.mutex will be held for this call
- */
-static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
-{
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct drm_plane *plane;
-
- /*
- * If we have an overlay plane associated with this CRTC, disable
- * it before the modeset to avoid its coordinates being outside
- * the new mode parameters. DRM doesn't provide help with this.
- */
- plane = dcrtc->plane;
- if (plane) {
- struct drm_framebuffer *fb = plane->fb;
-
- plane->funcs->disable_plane(plane);
- plane->fb = NULL;
- plane->crtc = NULL;
- drm_framebuffer_unreference(fb);
- }
-}
-
-/* The mode_config.mutex will be held for this call */
-static void armada_drm_crtc_commit(struct drm_crtc *crtc)
-{
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-
- if (dcrtc->dpms != DRM_MODE_DPMS_ON) {
- dcrtc->dpms = DRM_MODE_DPMS_ON;
- armada_drm_crtc_update(dcrtc);
- }
-}
-
-/* The mode_config.mutex will be held for this call */
-static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
- const struct drm_display_mode *mode, struct drm_display_mode *adj)
-{
- struct armada_private *priv = crtc->dev->dev_private;
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- int ret;
-
- /* We can't do interlaced modes if we don't have the SPU_ADV_REG */
- if (!priv->variant->has_spu_adv_reg &&
- adj->flags & DRM_MODE_FLAG_INTERLACE)
- return false;
-
- /* Check whether the display mode is possible */
- ret = priv->variant->crtc_compute_clock(dcrtc, adj, NULL);
- if (ret)
- return false;
-
- return true;
-}
-
-void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
-{
- struct armada_vbl_event *e, *n;
- void __iomem *base = dcrtc->base;
-
- if (stat & DMA_FF_UNDERFLOW)
- DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
- if (stat & GRA_FF_UNDERFLOW)
- DRM_ERROR("graphics underflow on crtc %u\n", dcrtc->num);
-
- if (stat & VSYNC_IRQ)
- drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);
-
- spin_lock(&dcrtc->irq_lock);
-
- list_for_each_entry_safe(e, n, &dcrtc->vbl_list, node) {
- list_del_init(&e->node);
- drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
- e->fn(dcrtc, e->data);
- }
-
- if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
- int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
- uint32_t val;
-
- writel_relaxed(dcrtc->v[i].spu_v_porch, base + LCD_SPU_V_PORCH);
- writel_relaxed(dcrtc->v[i].spu_v_h_total,
- base + LCD_SPUT_V_H_TOTAL);
-
- val = readl_relaxed(base + LCD_SPU_ADV_REG);
- val &= ~(ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF | ADV_VSYNCOFFEN);
- val |= dcrtc->v[i].spu_adv_reg;
- writel_relaxed(val, base + LCD_SPU_ADV_REG);
- }
-
- if (stat & DUMB_FRAMEDONE && dcrtc->cursor_update) {
- writel_relaxed(dcrtc->cursor_hw_pos,
- base + LCD_SPU_HWC_OVSA_HPXL_VLN);
- writel_relaxed(dcrtc->cursor_hw_sz,
- base + LCD_SPU_HWC_HPXL_VLN);
- armada_updatel(CFG_HWC_ENA,
- CFG_HWC_ENA | CFG_HWC_1BITMOD | CFG_HWC_1BITENA,
- base + LCD_SPU_DMA_CTRL0);
- dcrtc->cursor_update = false;
- armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
- }
-
- spin_unlock(&dcrtc->irq_lock);
-
- if (stat & GRA_FRAME_IRQ) {
- struct drm_device *dev = dcrtc->crtc.dev;
-
- spin_lock(&dev->event_lock);
- if (dcrtc->frame_work)
- armada_drm_crtc_complete_frame_work(dcrtc);
- spin_unlock(&dev->event_lock);
-
- wake_up(&dcrtc->frame_wait);
- }
-}
-
-/* These are locked by dev->vbl_lock */
-void armada_drm_crtc_disable_irq(struct armada_crtc *dcrtc, u32 mask)
-{
- if (dcrtc->irq_ena & mask) {
- dcrtc->irq_ena &= ~mask;
- writel(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
- }
-}
-
-void armada_drm_crtc_enable_irq(struct armada_crtc *dcrtc, u32 mask)
-{
- if ((dcrtc->irq_ena & mask) != mask) {
- dcrtc->irq_ena |= mask;
- writel(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
- if (readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR) & mask)
- writel(0, dcrtc->base + LCD_SPU_IRQ_ISR);
- }
-}
-
-static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc)
-{
- struct drm_display_mode *adj = &dcrtc->crtc.mode;
- uint32_t val = 0;
-
- if (dcrtc->csc_yuv_mode == CSC_YUV_CCIR709)
- val |= CFG_CSC_YUV_CCIR709;
- if (dcrtc->csc_rgb_mode == CSC_RGB_STUDIO)
- val |= CFG_CSC_RGB_STUDIO;
-
- /*
- * In auto mode, set the colorimetry, based upon the HDMI spec.
- * 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use
- * ITU601. It may be more appropriate to set this depending on
- * the source - but what if the graphic frame is YUV and the
- * video frame is RGB?
- */
- if ((adj->hdisplay == 1280 && adj->vdisplay == 720 &&
- !(adj->flags & DRM_MODE_FLAG_INTERLACE)) ||
- (adj->hdisplay == 1920 && adj->vdisplay == 1080)) {
- if (dcrtc->csc_yuv_mode == CSC_AUTO)
- val |= CFG_CSC_YUV_CCIR709;
- }
-
- /*
- * We assume we're connected to a TV-like device, so the YUV->RGB
- * conversion should produce a limited range. We should set this
- * depending on the connectors attached to this CRTC, and what
- * kind of device they report being connected.
- */
- if (dcrtc->csc_rgb_mode == CSC_AUTO)
- val |= CFG_CSC_RGB_STUDIO;
-
- return val;
-}
-
-/* The mode_config.mutex will be held for this call */
-static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode, struct drm_display_mode *adj,
- int x, int y, struct drm_framebuffer *old_fb)
-{
- struct armada_private *priv = crtc->dev->dev_private;
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_regs regs[17];
- uint32_t lm, rm, tm, bm, val, sclk;
- unsigned long flags;
- unsigned i;
- bool interlaced;
-
- drm_framebuffer_reference(crtc->fb);
-
- interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
-
- i = armada_drm_crtc_calc_fb(dcrtc->crtc.fb, x, y, regs, interlaced);
-
- rm = adj->crtc_hsync_start - adj->crtc_hdisplay;
- lm = adj->crtc_htotal - adj->crtc_hsync_end;
- bm = adj->crtc_vsync_start - adj->crtc_vdisplay;
- tm = adj->crtc_vtotal - adj->crtc_vsync_end;
-
- DRM_DEBUG_DRIVER("H: %d %d %d %d lm %d rm %d\n",
- adj->crtc_hdisplay,
- adj->crtc_hsync_start,
- adj->crtc_hsync_end,
- adj->crtc_htotal, lm, rm);
- DRM_DEBUG_DRIVER("V: %d %d %d %d tm %d bm %d\n",
- adj->crtc_vdisplay,
- adj->crtc_vsync_start,
- adj->crtc_vsync_end,
- adj->crtc_vtotal, tm, bm);
-
- /* Wait for pending flips to complete */
- wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
-
- drm_vblank_pre_modeset(crtc->dev, dcrtc->num);
-
- crtc->mode = *adj;
-
- val = dcrtc->dumb_ctrl & ~CFG_DUMB_ENA;
- if (val != dcrtc->dumb_ctrl) {
- dcrtc->dumb_ctrl = val;
- writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
- }
-
- /* Now compute the divider for real */
- priv->variant->crtc_compute_clock(dcrtc, adj, &sclk);
-
- /* Ensure graphic fifo is enabled */
- armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
- armada_reg_queue_set(regs, i, sclk, LCD_CFG_SCLK_DIV);
-
- if (interlaced ^ dcrtc->interlaced) {
- if (adj->flags & DRM_MODE_FLAG_INTERLACE)
- drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
- else
- drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
- dcrtc->interlaced = interlaced;
- }
-
- spin_lock_irqsave(&dcrtc->irq_lock, flags);
-
- /* Even interlaced/progressive frame */
- dcrtc->v[1].spu_v_h_total = adj->crtc_vtotal << 16 |
- adj->crtc_htotal;
- dcrtc->v[1].spu_v_porch = tm << 16 | bm;
- val = adj->crtc_hsync_start;
- dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
- priv->variant->spu_adv_reg;
-
- if (interlaced) {
- /* Odd interlaced frame */
- dcrtc->v[0].spu_v_h_total = dcrtc->v[1].spu_v_h_total +
- (1 << 16);
- dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1;
- val = adj->crtc_hsync_start - adj->crtc_htotal / 2;
- dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
- priv->variant->spu_adv_reg;
- } else {
- dcrtc->v[0] = dcrtc->v[1];
- }
-
- val = adj->crtc_vdisplay << 16 | adj->crtc_hdisplay;
-
- armada_reg_queue_set(regs, i, val, LCD_SPU_V_H_ACTIVE);
- armada_reg_queue_set(regs, i, val, LCD_SPU_GRA_HPXL_VLN);
- armada_reg_queue_set(regs, i, val, LCD_SPU_GZM_HPXL_VLN);
- armada_reg_queue_set(regs, i, (lm << 16) | rm, LCD_SPU_H_PORCH);
- armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_porch, LCD_SPU_V_PORCH);
- armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
- LCD_SPUT_V_H_TOTAL);
-
- if (priv->variant->has_spu_adv_reg) {
- armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg,
- ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF |
- ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
- }
-
- val = CFG_GRA_ENA | CFG_GRA_HSMOOTH;
- val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.fb)->fmt);
- val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.fb)->mod);
-
- if (drm_fb_to_armada_fb(dcrtc->crtc.fb)->fmt > CFG_420)
- val |= CFG_PALETTE_ENA;
-
- if (interlaced)
- val |= CFG_GRA_FTOGGLE;
-
- armada_reg_queue_mod(regs, i, val, CFG_GRAFORMAT |
- CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
- CFG_SWAPYU | CFG_YUV2RGB) |
- CFG_PALETTE_ENA | CFG_GRA_FTOGGLE,
- LCD_SPU_DMA_CTRL0);
-
- val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0;
- armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1);
-
- val = dcrtc->spu_iopad_ctrl | armada_drm_crtc_calculate_csc(dcrtc);
- armada_reg_queue_set(regs, i, val, LCD_SPU_IOPAD_CONTROL);
- armada_reg_queue_end(regs, i);
-
- armada_drm_crtc_update_regs(dcrtc, regs);
- spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-
- armada_drm_crtc_update(dcrtc);
-
- drm_vblank_post_modeset(crtc->dev, dcrtc->num);
- armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms));
-
- return 0;
-}
-
-/* The mode_config.mutex will be held for this call */
-static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
-{
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_regs regs[4];
- unsigned i;
-
- i = armada_drm_crtc_calc_fb(crtc->fb, crtc->x, crtc->y, regs,
- dcrtc->interlaced);
- armada_reg_queue_end(regs, i);
-
- /* Wait for pending flips to complete */
- wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
-
- /* Take a reference to the new fb as we're using it */
- drm_framebuffer_reference(crtc->fb);
-
- /* Update the base in the CRTC */
- armada_drm_crtc_update_regs(dcrtc, regs);
-
- /* Drop our previously held reference */
- armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms));
-
- return 0;
-}
-
-static void armada_drm_crtc_load_lut(struct drm_crtc *crtc)
-{
-}
-
-/* The mode_config.mutex will be held for this call */
-static void armada_drm_crtc_disable(struct drm_crtc *crtc)
-{
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-
- armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
- armada_drm_crtc_finish_fb(dcrtc, crtc->fb, true);
-
- /* Power down most RAMs and FIFOs */
- writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
- CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
- CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
-}
-
-static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
- .dpms = armada_drm_crtc_dpms,
- .prepare = armada_drm_crtc_prepare,
- .commit = armada_drm_crtc_commit,
- .mode_fixup = armada_drm_crtc_mode_fixup,
- .mode_set = armada_drm_crtc_mode_set,
- .mode_set_base = armada_drm_crtc_mode_set_base,
- .load_lut = armada_drm_crtc_load_lut,
- .disable = armada_drm_crtc_disable,
-};
-
-static void armada_load_cursor_argb(void __iomem *base, uint32_t *pix,
- unsigned stride, unsigned width, unsigned height)
-{
- uint32_t addr;
- unsigned y;
-
- addr = SRAM_HWC32_RAM1;
- for (y = 0; y < height; y++) {
- uint32_t *p = &pix[y * stride];
- unsigned x;
-
- for (x = 0; x < width; x++, p++) {
- uint32_t val = *p;
-
- val = (val & 0xff00ff00) |
- (val & 0x000000ff) << 16 |
- (val & 0x00ff0000) >> 16;
-
- writel_relaxed(val,
- base + LCD_SPU_SRAM_WRDAT);
- writel_relaxed(addr | SRAM_WRITE,
- base + LCD_SPU_SRAM_CTRL);
- addr += 1;
- if ((addr & 0x00ff) == 0)
- addr += 0xf00;
- if ((addr & 0x30ff) == 0)
- addr = SRAM_HWC32_RAM2;
- }
- }
-}
-
-static void armada_drm_crtc_cursor_tran(void __iomem *base)
-{
- unsigned addr;
-
- for (addr = 0; addr < 256; addr++) {
- /* write the default value */
- writel_relaxed(0x55555555, base + LCD_SPU_SRAM_WRDAT);
- writel_relaxed(addr | SRAM_WRITE | SRAM_HWC32_TRAN,
- base + LCD_SPU_SRAM_CTRL);
- }
-}
-
-static int armada_drm_crtc_cursor_update(struct armada_crtc *dcrtc, bool reload)
-{
- uint32_t xoff, xscr, w = dcrtc->cursor_w, s;
- uint32_t yoff, yscr, h = dcrtc->cursor_h;
- uint32_t para1;
-
- /*
- * Calculate the visible width and height of the cursor,
- * screen position, and the position in the cursor bitmap.
- */
- if (dcrtc->cursor_x < 0) {
- xoff = -dcrtc->cursor_x;
- xscr = 0;
- w -= min(xoff, w);
- } else if (dcrtc->cursor_x + w > dcrtc->crtc.mode.hdisplay) {
- xoff = 0;
- xscr = dcrtc->cursor_x;
- w = max_t(int, dcrtc->crtc.mode.hdisplay - dcrtc->cursor_x, 0);
- } else {
- xoff = 0;
- xscr = dcrtc->cursor_x;
- }
-
- if (dcrtc->cursor_y < 0) {
- yoff = -dcrtc->cursor_y;
- yscr = 0;
- h -= min(yoff, h);
- } else if (dcrtc->cursor_y + h > dcrtc->crtc.mode.vdisplay) {
- yoff = 0;
- yscr = dcrtc->cursor_y;
- h = max_t(int, dcrtc->crtc.mode.vdisplay - dcrtc->cursor_y, 0);
- } else {
- yoff = 0;
- yscr = dcrtc->cursor_y;
- }
-
- /* On interlaced modes, the vertical cursor size must be halved */
- s = dcrtc->cursor_w;
- if (dcrtc->interlaced) {
- s *= 2;
- yscr /= 2;
- h /= 2;
- }
-
- if (!dcrtc->cursor_obj || !h || !w) {
- spin_lock_irq(&dcrtc->irq_lock);
- armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
- dcrtc->cursor_update = false;
- armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
- spin_unlock_irq(&dcrtc->irq_lock);
- return 0;
- }
-
- para1 = readl_relaxed(dcrtc->base + LCD_SPU_SRAM_PARA1);
- armada_updatel(CFG_CSB_256x32, CFG_CSB_256x32 | CFG_PDWN256x32,
- dcrtc->base + LCD_SPU_SRAM_PARA1);
-
- /*
- * Initialize the transparency if the SRAM was powered down.
- * We must also reload the cursor data as well.
- */
- if (!(para1 & CFG_CSB_256x32)) {
- armada_drm_crtc_cursor_tran(dcrtc->base);
- reload = true;
- }
-
- if (dcrtc->cursor_hw_sz != (h << 16 | w)) {
- spin_lock_irq(&dcrtc->irq_lock);
- armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
- dcrtc->cursor_update = false;
- armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
- spin_unlock_irq(&dcrtc->irq_lock);
- reload = true;
- }
- if (reload) {
- struct armada_gem_object *obj = dcrtc->cursor_obj;
- uint32_t *pix;
- /* Set the top-left corner of the cursor image */
- pix = obj->addr;
- pix += yoff * s + xoff;
- armada_load_cursor_argb(dcrtc->base, pix, s, w, h);
- }
-
- /* Reload the cursor position, size and enable in the IRQ handler */
- spin_lock_irq(&dcrtc->irq_lock);
- dcrtc->cursor_hw_pos = yscr << 16 | xscr;
- dcrtc->cursor_hw_sz = h << 16 | w;
- dcrtc->cursor_update = true;
- armada_drm_crtc_enable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
- spin_unlock_irq(&dcrtc->irq_lock);
-
- return 0;
-}
-
-static void cursor_update(void *data)
-{
- armada_drm_crtc_cursor_update(data, true);
-}
-
-static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
- struct drm_file *file, uint32_t handle, uint32_t w, uint32_t h)
-{
- struct drm_device *dev = crtc->dev;
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_private *priv = crtc->dev->dev_private;
- struct armada_gem_object *obj = NULL;
- int ret;
-
- /* If no cursor support, replicate drm's return value */
- if (!priv->variant->has_spu_adv_reg)
- return -ENXIO;
-
- if (handle && w > 0 && h > 0) {
- /* maximum size is 64x32 or 32x64 */
- if (w > 64 || h > 64 || (w > 32 && h > 32))
- return -ENOMEM;
-
- obj = armada_gem_object_lookup(dev, file, handle);
- if (!obj)
- return -ENOENT;
-
- /* Must be a kernel-mapped object */
- if (!obj->addr) {
- drm_gem_object_unreference_unlocked(&obj->obj);
- return -EINVAL;
- }
-
- if (obj->obj.size < w * h * 4) {
- DRM_ERROR("buffer is too small\n");
- drm_gem_object_unreference_unlocked(&obj->obj);
- return -ENOMEM;
- }
- }
-
- mutex_lock(&dev->struct_mutex);
- if (dcrtc->cursor_obj) {
- dcrtc->cursor_obj->update = NULL;
- dcrtc->cursor_obj->update_data = NULL;
- drm_gem_object_unreference(&dcrtc->cursor_obj->obj);
- }
- dcrtc->cursor_obj = obj;
- dcrtc->cursor_w = w;
- dcrtc->cursor_h = h;
- ret = armada_drm_crtc_cursor_update(dcrtc, true);
- if (obj) {
- obj->update_data = dcrtc;
- obj->update = cursor_update;
- }
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
-
-static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
- struct drm_device *dev = crtc->dev;
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_private *priv = crtc->dev->dev_private;
- int ret;
-
- /* If no cursor support, replicate drm's return value */
- if (!priv->variant->has_spu_adv_reg)
- return -EFAULT;
-
- mutex_lock(&dev->struct_mutex);
- dcrtc->cursor_x = x;
- dcrtc->cursor_y = y;
- ret = armada_drm_crtc_cursor_update(dcrtc, false);
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
-
-static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
-{
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_private *priv = crtc->dev->dev_private;
-
- if (dcrtc->cursor_obj)
- drm_gem_object_unreference(&dcrtc->cursor_obj->obj);
-
- priv->dcrtc[dcrtc->num] = NULL;
- drm_crtc_cleanup(&dcrtc->crtc);
-
- if (!IS_ERR(dcrtc->clk))
- clk_disable_unprepare(dcrtc->clk);
-
- kfree(dcrtc);
-}
-
-/*
- * The mode_config lock is held here, to prevent races between this
- * and a mode_set.
- */
-static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
- struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
-{
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_frame_work *work;
- struct drm_device *dev = crtc->dev;
- unsigned long flags;
- unsigned i;
- int ret;
-
- /* We don't support changing the pixel format */
- if (fb->pixel_format != crtc->fb->pixel_format)
- return -EINVAL;
-
- work = kmalloc(sizeof(*work), GFP_KERNEL);
- if (!work)
- return -ENOMEM;
-
- work->event = event;
- work->old_fb = dcrtc->crtc.fb;
-
- i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs,
- dcrtc->interlaced);
- armada_reg_queue_end(work->regs, i);
-
- /*
- * Hold the old framebuffer for the work - DRM appears to drop our
- * reference to the old framebuffer in drm_mode_page_flip_ioctl().
- */
- drm_framebuffer_reference(work->old_fb);
-
- ret = armada_drm_crtc_queue_frame_work(dcrtc, work);
- if (ret) {
- /*
- * Undo our reference above; DRM does not drop the reference
- * to this object on error, so that's okay.
- */
- drm_framebuffer_unreference(work->old_fb);
- kfree(work);
- return ret;
- }
-
- /*
- * Don't take a reference on the new framebuffer;
- * drm_mode_page_flip_ioctl() has already grabbed a reference and
- * will _not_ drop that reference on successful return from this
- * function. Simply mark this new framebuffer as the current one.
- */
- dcrtc->crtc.fb = fb;
-
- /*
- * Finally, if the display is blanked, we won't receive an
- * interrupt, so complete it now.
- */
- if (dpms_blanked(dcrtc->dpms)) {
- spin_lock_irqsave(&dev->event_lock, flags);
- if (dcrtc->frame_work)
- armada_drm_crtc_complete_frame_work(dcrtc);
- spin_unlock_irqrestore(&dev->event_lock, flags);
- }
-
- return 0;
-}
-
-static int
-armada_drm_crtc_set_property(struct drm_crtc *crtc,
- struct drm_property *property, uint64_t val)
-{
- struct armada_private *priv = crtc->dev->dev_private;
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- bool update_csc = false;
-
- if (property == priv->csc_yuv_prop) {
- dcrtc->csc_yuv_mode = val;
- update_csc = true;
- } else if (property == priv->csc_rgb_prop) {
- dcrtc->csc_rgb_mode = val;
- update_csc = true;
- }
-
- if (update_csc) {
- uint32_t val;
-
- val = dcrtc->spu_iopad_ctrl |
- armada_drm_crtc_calculate_csc(dcrtc);
- writel_relaxed(val, dcrtc->base + LCD_SPU_IOPAD_CONTROL);
- }
-
- return 0;
-}
-
-static struct drm_crtc_funcs armada_crtc_funcs = {
- .cursor_set = armada_drm_crtc_cursor_set,
- .cursor_move = armada_drm_crtc_cursor_move,
- .destroy = armada_drm_crtc_destroy,
- .set_config = drm_crtc_helper_set_config,
- .page_flip = armada_drm_crtc_page_flip,
- .set_property = armada_drm_crtc_set_property,
-};
-
-static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
- { CSC_AUTO, "Auto" },
- { CSC_YUV_CCIR601, "CCIR601" },
- { CSC_YUV_CCIR709, "CCIR709" },
-};
-
-static struct drm_prop_enum_list armada_drm_csc_rgb_enum_list[] = {
- { CSC_AUTO, "Auto" },
- { CSC_RGB_COMPUTER, "Computer system" },
- { CSC_RGB_STUDIO, "Studio" },
-};
-
-static int armada_drm_crtc_create_properties(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
-
- if (priv->csc_yuv_prop)
- return 0;
-
- priv->csc_yuv_prop = drm_property_create_enum(dev, 0,
- "CSC_YUV", armada_drm_csc_yuv_enum_list,
- ARRAY_SIZE(armada_drm_csc_yuv_enum_list));
- priv->csc_rgb_prop = drm_property_create_enum(dev, 0,
- "CSC_RGB", armada_drm_csc_rgb_enum_list,
- ARRAY_SIZE(armada_drm_csc_rgb_enum_list));
-
- if (!priv->csc_yuv_prop || !priv->csc_rgb_prop)
- return -ENOMEM;
-
- return 0;
-}
-
-int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
- struct resource *res)
-{
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc;
- void __iomem *base;
- int ret;
-
- ret = armada_drm_crtc_create_properties(dev);
- if (ret)
- return ret;
-
- base = devm_request_and_ioremap(dev->dev, res);
- if (!base) {
- DRM_ERROR("failed to ioremap register\n");
- return -ENOMEM;
- }
-
- dcrtc = kzalloc(sizeof(*dcrtc), GFP_KERNEL);
- if (!dcrtc) {
- DRM_ERROR("failed to allocate Armada crtc\n");
- return -ENOMEM;
- }
-
- dcrtc->base = base;
- dcrtc->num = num;
- dcrtc->clk = ERR_PTR(-EINVAL);
- dcrtc->csc_yuv_mode = CSC_AUTO;
- dcrtc->csc_rgb_mode = CSC_AUTO;
- dcrtc->cfg_dumb_ctrl = DUMB24_RGB888_0;
- dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
- spin_lock_init(&dcrtc->irq_lock);
- dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
- INIT_LIST_HEAD(&dcrtc->vbl_list);
- init_waitqueue_head(&dcrtc->frame_wait);
-
- /* Initialize some registers which we don't otherwise set */
- writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV);
- writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_BLANKCOLOR);
- writel_relaxed(dcrtc->spu_iopad_ctrl,
- dcrtc->base + LCD_SPU_IOPAD_CONTROL);
- writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_SRAM_PARA0);
- writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
- CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
- CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
- writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1);
- writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN);
-
- if (priv->variant->crtc_init) {
- ret = priv->variant->crtc_init(dcrtc);
- if (ret) {
- kfree(dcrtc);
- return ret;
- }
- }
-
- /* Ensure AXI pipeline is enabled */
- armada_updatel(CFG_ARBFAST_ENA, 0, dcrtc->base + LCD_SPU_DMA_CTRL0);
-
- priv->dcrtc[dcrtc->num] = dcrtc;
-
- drm_crtc_init(dev, &dcrtc->crtc, &armada_crtc_funcs);
- drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
-
- drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop,
- dcrtc->csc_yuv_mode);
- drm_object_attach_property(&dcrtc->crtc.base, priv->csc_rgb_prop,
- dcrtc->csc_rgb_mode);
-
- return armada_overlay_plane_create(dev, 1 << dcrtc->num);
-}
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
deleted file mode 100644
index 9c10a07..0000000
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_CRTC_H
-#define ARMADA_CRTC_H
-
-struct armada_gem_object;
-
-struct armada_regs {
- uint32_t offset;
- uint32_t mask;
- uint32_t val;
-};
-
-#define armada_reg_queue_mod(_r, _i, _v, _m, _o) \
- do { \
- struct armada_regs *__reg = _r; \
- __reg[_i].offset = _o; \
- __reg[_i].mask = ~(_m); \
- __reg[_i].val = _v; \
- _i++; \
- } while (0)
-
-#define armada_reg_queue_set(_r, _i, _v, _o) \
- armada_reg_queue_mod(_r, _i, _v, ~0, _o)
-
-#define armada_reg_queue_end(_r, _i) \
- armada_reg_queue_mod(_r, _i, 0, 0, ~0)
-
-struct armada_frame_work;
-
-struct armada_crtc {
- struct drm_crtc crtc;
- unsigned num;
- void __iomem *base;
- struct clk *clk;
- struct {
- uint32_t spu_v_h_total;
- uint32_t spu_v_porch;
- uint32_t spu_adv_reg;
- } v[2];
- bool interlaced;
- bool cursor_update;
- uint8_t csc_yuv_mode;
- uint8_t csc_rgb_mode;
-
- struct drm_plane *plane;
-
- struct armada_gem_object *cursor_obj;
- int cursor_x;
- int cursor_y;
- uint32_t cursor_hw_pos;
- uint32_t cursor_hw_sz;
- uint32_t cursor_w;
- uint32_t cursor_h;
-
- int dpms;
- uint32_t cfg_dumb_ctrl;
- uint32_t dumb_ctrl;
- uint32_t spu_iopad_ctrl;
-
- wait_queue_head_t frame_wait;
- struct armada_frame_work *frame_work;
-
- spinlock_t irq_lock;
- uint32_t irq_ena;
- struct list_head vbl_list;
-};
-#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
-
-int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *);
-void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
-void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
-void armada_drm_crtc_irq(struct armada_crtc *, u32);
-void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
-void armada_drm_crtc_enable_irq(struct armada_crtc *, u32);
-void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
-
-#endif
diff --git a/drivers/gpu/drm/armada/armada_debugfs.c b/drivers/gpu/drm/armada/armada_debugfs.c
deleted file mode 100644
index 471e456..0000000
--- a/drivers/gpu/drm/armada/armada_debugfs.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- * Rewritten from the dovefb driver, and Armada510 manuals.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/ctype.h>
-#include <linux/debugfs.h>
-#include <linux/module.h>
-#include <linux/seq_file.h>
-#include <drm/drmP.h>
-#include "armada_crtc.h"
-#include "armada_drm.h"
-
-static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = m->private;
- struct drm_device *dev = node->minor->dev;
- struct armada_private *priv = dev->dev_private;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_mm_dump_table(m, &priv->linear);
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
-
-static int armada_debugfs_reg_show(struct seq_file *m, void *data)
-{
- struct drm_device *dev = m->private;
- struct armada_private *priv = dev->dev_private;
- int n, i;
-
- if (priv) {
- for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
- struct armada_crtc *dcrtc = priv->dcrtc[n];
- if (!dcrtc)
- continue;
-
- for (i = 0x84; i <= 0x1c4; i += 4) {
- uint32_t v = readl_relaxed(dcrtc->base + i);
- seq_printf(m, "%u: 0x%04x: 0x%08x\n", n, i, v);
- }
- }
- }
-
- return 0;
-}
-
-static int armada_debugfs_reg_r_open(struct inode *inode, struct file *file)
-{
- return single_open(file, armada_debugfs_reg_show, inode->i_private);
-}
-
-static const struct file_operations fops_reg_r = {
- .owner = THIS_MODULE,
- .open = armada_debugfs_reg_r_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int armada_debugfs_write(struct file *file, const char __user *ptr,
- size_t len, loff_t *off)
-{
- struct drm_device *dev = file->private_data;
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc = priv->dcrtc[0];
- char buf[32], *p;
- uint32_t reg, val;
- int ret;
-
- if (*off != 0)
- return 0;
-
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
-
- ret = strncpy_from_user(buf, ptr, len);
- if (ret < 0)
- return ret;
- buf[len] = '\0';
-
- reg = simple_strtoul(buf, &p, 16);
- if (!isspace(*p))
- return -EINVAL;
- val = simple_strtoul(p + 1, NULL, 16);
-
- if (reg >= 0x84 && reg <= 0x1c4)
- writel(val, dcrtc->base + reg);
-
- return len;
-}
-
-static const struct file_operations fops_reg_w = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .write = armada_debugfs_write,
- .llseek = noop_llseek,
-};
-
-static struct drm_info_list armada_debugfs_list[] = {
- { "gem_linear", armada_debugfs_gem_linear_show, 0 },
-};
-#define ARMADA_DEBUGFS_ENTRIES ARRAY_SIZE(armada_debugfs_list)
-
-static int drm_add_fake_info_node(struct drm_minor *minor, struct dentry *ent,
- const void *key)
-{
- struct drm_info_node *node;
-
- node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
- if (node == NULL) {
- debugfs_remove(ent);
- return -ENOMEM;
- }
-
- node->minor = minor;
- node->dent = ent;
- node->info_ent = (void *) key;
-
- mutex_lock(&minor->debugfs_lock);
- list_add(&node->list, &minor->debugfs_list);
- mutex_unlock(&minor->debugfs_lock);
-
- return 0;
-}
-
-static int armada_debugfs_create(struct dentry *root, struct drm_minor *minor,
- const char *name, umode_t mode, const struct file_operations *fops)
-{
- struct dentry *de;
-
- de = debugfs_create_file(name, mode, root, minor->dev, fops);
-
- return drm_add_fake_info_node(minor, de, fops);
-}
-
-int armada_drm_debugfs_init(struct drm_minor *minor)
-{
- int ret;
-
- ret = drm_debugfs_create_files(armada_debugfs_list,
- ARMADA_DEBUGFS_ENTRIES,
- minor->debugfs_root, minor);
- if (ret)
- return ret;
-
- ret = armada_debugfs_create(minor->debugfs_root, minor,
- "reg", S_IFREG | S_IRUSR, &fops_reg_r);
- if (ret)
- goto err_1;
-
- ret = armada_debugfs_create(minor->debugfs_root, minor,
- "reg_wr", S_IFREG | S_IWUSR, &fops_reg_w);
- if (ret)
- goto err_2;
- return ret;
-
- err_2:
- drm_debugfs_remove_files((struct drm_info_list *)&fops_reg_r, 1, minor);
- err_1:
- drm_debugfs_remove_files(armada_debugfs_list, ARMADA_DEBUGFS_ENTRIES,
- minor);
- return ret;
-}
-
-void armada_drm_debugfs_cleanup(struct drm_minor *minor)
-{
- drm_debugfs_remove_files((struct drm_info_list *)&fops_reg_w, 1, minor);
- drm_debugfs_remove_files((struct drm_info_list *)&fops_reg_r, 1, minor);
- drm_debugfs_remove_files(armada_debugfs_list, ARMADA_DEBUGFS_ENTRIES,
- minor);
-}
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
deleted file mode 100644
index eef09ec..0000000
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_DRM_H
-#define ARMADA_DRM_H
-
-#include <linux/kfifo.h>
-#include <linux/io.h>
-#include <linux/workqueue.h>
-#include <drm/drmP.h>
-
-struct armada_crtc;
-struct armada_gem_object;
-struct clk;
-struct drm_fb_helper;
-
-static inline void
-armada_updatel(uint32_t val, uint32_t mask, void __iomem *ptr)
-{
- uint32_t ov, v;
-
- ov = v = readl_relaxed(ptr);
- v = (v & ~mask) | val;
- if (ov != v)
- writel_relaxed(v, ptr);
-}
-
-static inline uint32_t armada_pitch(uint32_t width, uint32_t bpp)
-{
- uint32_t pitch = bpp != 4 ? width * ((bpp + 7) / 8) : width / 2;
-
- /* 88AP510 spec recommends pitch be a multiple of 128 */
- return ALIGN(pitch, 128);
-}
-
-struct armada_vbl_event {
- struct list_head node;
- void *data;
- void (*fn)(struct armada_crtc *, void *);
-};
-void armada_drm_vbl_event_add(struct armada_crtc *,
- struct armada_vbl_event *);
-void armada_drm_vbl_event_remove(struct armada_crtc *,
- struct armada_vbl_event *);
-void armada_drm_vbl_event_remove_unlocked(struct armada_crtc *,
- struct armada_vbl_event *);
-#define armada_drm_vbl_event_init(_e, _f, _d) do { \
- struct armada_vbl_event *__e = _e; \
- INIT_LIST_HEAD(&__e->node); \
- __e->data = _d; \
- __e->fn = _f; \
-} while (0)
-
-
-struct armada_private;
-
-struct armada_variant {
- bool has_spu_adv_reg;
- uint32_t spu_adv_reg;
- int (*init)(struct armada_private *, struct device *);
- int (*crtc_init)(struct armada_crtc *);
- int (*crtc_compute_clock)(struct armada_crtc *,
- const struct drm_display_mode *,
- uint32_t *);
-};
-
-/* Variant ops */
-extern const struct armada_variant armada510_ops;
-
-struct armada_private {
- const struct armada_variant *variant;
- struct work_struct fb_unref_work;
- DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
- struct drm_fb_helper *fbdev;
- struct armada_crtc *dcrtc[2];
- struct drm_mm linear;
- struct clk *extclk[2];
- struct drm_property *csc_yuv_prop;
- struct drm_property *csc_rgb_prop;
- struct drm_property *colorkey_prop;
- struct drm_property *colorkey_min_prop;
- struct drm_property *colorkey_max_prop;
- struct drm_property *colorkey_val_prop;
- struct drm_property *colorkey_alpha_prop;
- struct drm_property *colorkey_mode_prop;
- struct drm_property *brightness_prop;
- struct drm_property *contrast_prop;
- struct drm_property *saturation_prop;
-#ifdef CONFIG_DEBUG_FS
- struct dentry *de;
-#endif
-};
-
-void __armada_drm_queue_unref_work(struct drm_device *,
- struct drm_framebuffer *);
-void armada_drm_queue_unref_work(struct drm_device *,
- struct drm_framebuffer *);
-
-extern const struct drm_mode_config_funcs armada_drm_mode_config_funcs;
-
-int armada_fbdev_init(struct drm_device *);
-void armada_fbdev_fini(struct drm_device *);
-
-int armada_overlay_plane_create(struct drm_device *, unsigned long);
-
-int armada_drm_debugfs_init(struct drm_minor *);
-void armada_drm_debugfs_cleanup(struct drm_minor *);
-
-#endif
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
deleted file mode 100644
index 4f2b283..0000000
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include "armada_crtc.h"
-#include "armada_drm.h"
-#include "armada_gem.h"
-#include "armada_hw.h"
-#include <drm/armada_drm.h>
-#include "armada_ioctlP.h"
-
-#ifdef CONFIG_DRM_ARMADA_TDA1998X
-#include <drm/i2c/tda998x.h>
-#include "armada_slave.h"
-
-static struct tda998x_encoder_params params = {
- /* With 0x24, there is no translation between vp_out and int_vp
- FB LCD out Pins VIP Int Vp
- R:23:16 R:7:0 VPC7:0 7:0 7:0[R]
- G:15:8 G:15:8 VPB7:0 23:16 23:16[G]
- B:7:0 B:23:16 VPA7:0 15:8 15:8[B]
- */
- .swap_a = 2,
- .swap_b = 3,
- .swap_c = 4,
- .swap_d = 5,
- .swap_e = 0,
- .swap_f = 1,
- .audio_cfg = BIT(2),
- .audio_frame[1] = 1,
- .audio_format = AFMT_SPDIF,
- .audio_sample_rate = 44100,
-};
-
-static const struct armada_drm_slave_config tda19988_config = {
- .i2c_adapter_id = 0,
- .crtcs = 1 << 0, /* Only LCD0 at the moment */
- .polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT,
- .interlace_allowed = true,
- .info = {
- .type = "tda998x",
- .addr = 0x70,
- .platform_data = &params,
- },
-};
-#endif
-
-static void armada_drm_unref_work(struct work_struct *work)
-{
- struct armada_private *priv =
- container_of(work, struct armada_private, fb_unref_work);
- struct drm_framebuffer *fb;
-
- while (kfifo_get(&priv->fb_unref, &fb))
- drm_framebuffer_unreference(fb);
-}
-
-/* Must be called with dev->event_lock held */
-void __armada_drm_queue_unref_work(struct drm_device *dev,
- struct drm_framebuffer *fb)
-{
- struct armada_private *priv = dev->dev_private;
-
- /*
- * Yes, we really must jump through these hoops just to store a
- * _pointer_ to something into the kfifo. This is utterly insane
- * and idiotic, because it kfifo requires the _data_ pointed to by
- * the pointer const, not the pointer itself. Not only that, but
- * you have to pass a pointer _to_ the pointer you want stored.
- */
- const struct drm_framebuffer *silly_api_alert = fb;
- WARN_ON(!kfifo_put(&priv->fb_unref, &silly_api_alert));
- schedule_work(&priv->fb_unref_work);
-}
-
-void armada_drm_queue_unref_work(struct drm_device *dev,
- struct drm_framebuffer *fb)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->event_lock, flags);
- __armada_drm_queue_unref_work(dev, fb);
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
-static int armada_drm_load(struct drm_device *dev, unsigned long flags)
-{
- const struct platform_device_id *id;
- struct armada_private *priv;
- struct resource *res[ARRAY_SIZE(priv->dcrtc)];
- struct resource *mem = NULL;
- int ret, n, i;
-
- memset(res, 0, sizeof(res));
-
- for (n = i = 0; ; n++) {
- struct resource *r = platform_get_resource(dev->platformdev,
- IORESOURCE_MEM, n);
- if (!r)
- break;
-
- /* Resources above 64K are graphics memory */
- if (resource_size(r) > SZ_64K)
- mem = r;
- else if (i < ARRAY_SIZE(priv->dcrtc))
- res[i++] = r;
- else
- return -EINVAL;
- }
-
- if (!res[0] || !mem)
- return -ENXIO;
-
- if (!devm_request_mem_region(dev->dev, mem->start,
- resource_size(mem), "armada-drm"))
- return -EBUSY;
-
- priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- DRM_ERROR("failed to allocate private\n");
- return -ENOMEM;
- }
-
- dev->dev_private = priv;
-
- /* Get the implementation specific driver data. */
- id = platform_get_device_id(dev->platformdev);
- if (!id)
- return -ENXIO;
-
- priv->variant = (struct armada_variant *)id->driver_data;
-
- ret = priv->variant->init(priv, dev->dev);
- if (ret)
- return ret;
-
- INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
- INIT_KFIFO(priv->fb_unref);
-
- /* Mode setting support */
- drm_mode_config_init(dev);
- dev->mode_config.min_width = 320;
- dev->mode_config.min_height = 200;
-
- /*
- * With vscale enabled, the maximum width is 1920 due to the
- * 1920 by 3 lines RAM
- */
- dev->mode_config.max_width = 1920;
- dev->mode_config.max_height = 2048;
-
- dev->mode_config.preferred_depth = 24;
- dev->mode_config.funcs = &armada_drm_mode_config_funcs;
- drm_mm_init(&priv->linear, mem->start, resource_size(mem));
-
- /* Create all LCD controllers */
- for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
- if (!res[n])
- break;
-
- ret = armada_drm_crtc_create(dev, n, res[n]);
- if (ret)
- goto err_kms;
- }
-
-#ifdef CONFIG_DRM_ARMADA_TDA1998X
- ret = armada_drm_connector_slave_create(dev, &tda19988_config);
- if (ret)
- goto err_kms;
-#endif
-
- ret = drm_vblank_init(dev, n);
- if (ret)
- goto err_kms;
-
- ret = drm_irq_install(dev);
- if (ret)
- goto err_kms;
-
- dev->vblank_disable_allowed = 1;
-
- ret = armada_fbdev_init(dev);
- if (ret)
- goto err_irq;
-
- drm_kms_helper_poll_init(dev);
-
- return 0;
-
- err_irq:
- drm_irq_uninstall(dev);
- err_kms:
- drm_mode_config_cleanup(dev);
- drm_mm_takedown(&priv->linear);
- flush_work(&priv->fb_unref_work);
-
- return ret;
-}
-
-static int armada_drm_unload(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
-
- drm_kms_helper_poll_fini(dev);
- armada_fbdev_fini(dev);
- drm_irq_uninstall(dev);
- drm_mode_config_cleanup(dev);
- drm_mm_takedown(&priv->linear);
- flush_work(&priv->fb_unref_work);
- dev->dev_private = NULL;
-
- return 0;
-}
-
-void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
- struct armada_vbl_event *evt)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dcrtc->irq_lock, flags);
- if (list_empty(&evt->node)) {
- list_add_tail(&evt->node, &dcrtc->vbl_list);
-
- drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
- }
- spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
-void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
- struct armada_vbl_event *evt)
-{
- if (!list_empty(&evt->node)) {
- list_del_init(&evt->node);
- drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
- }
-}
-
-void armada_drm_vbl_event_remove_unlocked(struct armada_crtc *dcrtc,
- struct armada_vbl_event *evt)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dcrtc->irq_lock, flags);
- armada_drm_vbl_event_remove(dcrtc, evt);
- spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
-/* These are called under the vbl_lock. */
-static int armada_drm_enable_vblank(struct drm_device *dev, int crtc)
-{
- struct armada_private *priv = dev->dev_private;
- armada_drm_crtc_enable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
- return 0;
-}
-
-static void armada_drm_disable_vblank(struct drm_device *dev, int crtc)
-{
- struct armada_private *priv = dev->dev_private;
- armada_drm_crtc_disable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
-}
-
-static irqreturn_t armada_drm_irq_handler(int irq, void *arg)
-{
- struct drm_device *dev = arg;
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc = priv->dcrtc[0];
- uint32_t v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
- irqreturn_t handled = IRQ_NONE;
-
- /*
- * This is rediculous - rather than writing bits to clear, we
- * have to set the actual status register value. This is racy.
- */
- writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
-
- /* Mask out those interrupts we haven't enabled */
- v = stat & dcrtc->irq_ena;
-
- if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
- armada_drm_crtc_irq(dcrtc, stat);
- handled = IRQ_HANDLED;
- }
-
- return handled;
-}
-
-static int armada_drm_irq_postinstall(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc = priv->dcrtc[0];
-
- spin_lock_irq(&dev->vbl_lock);
- writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
- writel(0, dcrtc->base + LCD_SPU_IRQ_ISR);
- spin_unlock_irq(&dev->vbl_lock);
-
- return 0;
-}
-
-static void armada_drm_irq_uninstall(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc = priv->dcrtc[0];
-
- writel(0, dcrtc->base + LCD_SPU_IRQ_ENA);
-}
-
-static struct drm_ioctl_desc armada_ioctls[] = {
- DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,
- DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(ARMADA_GEM_MMAP, armada_gem_mmap_ioctl,
- DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(ARMADA_GEM_PWRITE, armada_gem_pwrite_ioctl,
- DRM_UNLOCKED),
-};
-
-static const struct file_operations armada_drm_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = drm_read,
- .poll = drm_poll,
- .unlocked_ioctl = drm_ioctl,
- .mmap = drm_gem_mmap,
- .open = drm_open,
- .release = drm_release,
-};
-
-static struct drm_driver armada_drm_driver = {
- .load = armada_drm_load,
- .open = NULL,
- .preclose = NULL,
- .postclose = NULL,
- .lastclose = NULL,
- .unload = armada_drm_unload,
- .get_vblank_counter = drm_vblank_count,
- .enable_vblank = armada_drm_enable_vblank,
- .disable_vblank = armada_drm_disable_vblank,
- .irq_handler = armada_drm_irq_handler,
- .irq_postinstall = armada_drm_irq_postinstall,
- .irq_uninstall = armada_drm_irq_uninstall,
-#ifdef CONFIG_DEBUG_FS
- .debugfs_init = armada_drm_debugfs_init,
- .debugfs_cleanup = armada_drm_debugfs_cleanup,
-#endif
- .gem_free_object = armada_gem_free_object,
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
- .gem_prime_export = armada_gem_prime_export,
- .gem_prime_import = armada_gem_prime_import,
- .dumb_create = armada_gem_dumb_create,
- .dumb_map_offset = armada_gem_dumb_map_offset,
- .dumb_destroy = armada_gem_dumb_destroy,
- .gem_vm_ops = &armada_gem_vm_ops,
- .major = 1,
- .minor = 0,
- .name = "armada-drm",
- .desc = "Armada SoC DRM",
- .date = "20120730",
- .driver_features = DRIVER_GEM | DRIVER_MODESET |
- DRIVER_HAVE_IRQ | DRIVER_PRIME,
- .ioctls = armada_ioctls,
- .fops = &armada_drm_fops,
-};
-
-static int armada_drm_probe(struct platform_device *pdev)
-{
- return drm_platform_init(&armada_drm_driver, pdev);
-}
-
-static int armada_drm_remove(struct platform_device *pdev)
-{
- drm_platform_exit(&armada_drm_driver, pdev);
- return 0;
-}
-
-static const struct platform_device_id armada_drm_platform_ids[] = {
- {
- .name = "armada-drm",
- .driver_data = (unsigned long)&armada510_ops,
- }, {
- .name = "armada-510-drm",
- .driver_data = (unsigned long)&armada510_ops,
- },
- { },
-};
-MODULE_DEVICE_TABLE(platform, armada_drm_platform_ids);
-
-static struct platform_driver armada_drm_platform_driver = {
- .probe = armada_drm_probe,
- .remove = armada_drm_remove,
- .driver = {
- .name = "armada-drm",
- .owner = THIS_MODULE,
- },
- .id_table = armada_drm_platform_ids,
-};
-
-static int __init armada_drm_init(void)
-{
- armada_drm_driver.num_ioctls = DRM_ARRAY_SIZE(armada_ioctls);
- return platform_driver_register(&armada_drm_platform_driver);
-}
-module_init(armada_drm_init);
-
-static void __exit armada_drm_exit(void)
-{
- platform_driver_unregister(&armada_drm_platform_driver);
-}
-module_exit(armada_drm_exit);
-
-MODULE_AUTHOR("Russell King <rmk+kernel@arm.linux.org.uk>");
-MODULE_DESCRIPTION("Armada DRM Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:armada-drm");
diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c
deleted file mode 100644
index 1c90969..0000000
--- a/drivers/gpu/drm/armada/armada_fb.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_fb_helper.h>
-#include "armada_drm.h"
-#include "armada_fb.h"
-#include "armada_gem.h"
-#include "armada_hw.h"
-
-static void armada_fb_destroy(struct drm_framebuffer *fb)
-{
- struct armada_framebuffer *dfb = drm_fb_to_armada_fb(fb);
-
- drm_framebuffer_cleanup(&dfb->fb);
- drm_gem_object_unreference_unlocked(&dfb->obj->obj);
- kfree(dfb);
-}
-
-static int armada_fb_create_handle(struct drm_framebuffer *fb,
- struct drm_file *dfile, unsigned int *handle)
-{
- struct armada_framebuffer *dfb = drm_fb_to_armada_fb(fb);
- return drm_gem_handle_create(dfile, &dfb->obj->obj, handle);
-}
-
-static const struct drm_framebuffer_funcs armada_fb_funcs = {
- .destroy = armada_fb_destroy,
- .create_handle = armada_fb_create_handle,
-};
-
-struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
- struct drm_mode_fb_cmd2 *mode, struct armada_gem_object *obj)
-{
- struct armada_framebuffer *dfb;
- uint8_t format, config;
- int ret;
-
- switch (mode->pixel_format) {
-#define FMT(drm, fmt, mod) \
- case DRM_FORMAT_##drm: \
- format = CFG_##fmt; \
- config = mod; \
- break
- FMT(RGB565, 565, CFG_SWAPRB);
- FMT(BGR565, 565, 0);
- FMT(ARGB1555, 1555, CFG_SWAPRB);
- FMT(ABGR1555, 1555, 0);
- FMT(RGB888, 888PACK, CFG_SWAPRB);
- FMT(BGR888, 888PACK, 0);
- FMT(XRGB8888, X888, CFG_SWAPRB);
- FMT(XBGR8888, X888, 0);
- FMT(ARGB8888, 8888, CFG_SWAPRB);
- FMT(ABGR8888, 8888, 0);
- FMT(YUYV, 422PACK, CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV);
- FMT(UYVY, 422PACK, CFG_YUV2RGB);
- FMT(VYUY, 422PACK, CFG_YUV2RGB | CFG_SWAPUV);
- FMT(YVYU, 422PACK, CFG_YUV2RGB | CFG_SWAPYU);
- FMT(YUV422, 422, CFG_YUV2RGB);
- FMT(YVU422, 422, CFG_YUV2RGB | CFG_SWAPUV);
- FMT(YUV420, 420, CFG_YUV2RGB);
- FMT(YVU420, 420, CFG_YUV2RGB | CFG_SWAPUV);
- FMT(C8, PSEUDO8, 0);
-#undef FMT
- default:
- return ERR_PTR(-EINVAL);
- }
-
- dfb = kzalloc(sizeof(*dfb), GFP_KERNEL);
- if (!dfb) {
- DRM_ERROR("failed to allocate Armada fb object\n");
- return ERR_PTR(-ENOMEM);
- }
-
- dfb->fmt = format;
- dfb->mod = config;
- dfb->obj = obj;
-
- drm_helper_mode_fill_fb_struct(&dfb->fb, mode);
-
- ret = drm_framebuffer_init(dev, &dfb->fb, &armada_fb_funcs);
- if (ret) {
- kfree(dfb);
- return ERR_PTR(ret);
- }
-
- /*
- * Take a reference on our object as we're successful - the
- * caller already holds a reference, which keeps us safe for
- * the above call, but the caller will drop their reference
- * to it. Hence we need to take our own reference.
- */
- drm_gem_object_reference(&obj->obj);
-
- return dfb;
-}
-
-static struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
- struct drm_file *dfile, struct drm_mode_fb_cmd2 *mode)
-{
- struct armada_gem_object *obj;
- struct armada_framebuffer *dfb;
- int ret;
-
- DRM_DEBUG_DRIVER("w%u h%u pf%08x f%u p%u,%u,%u\n",
- mode->width, mode->height, mode->pixel_format,
- mode->flags, mode->pitches[0], mode->pitches[1],
- mode->pitches[2]);
-
- /* We can only handle a single plane at the moment */
- if (drm_format_num_planes(mode->pixel_format) > 1 &&
- (mode->handles[0] != mode->handles[1] ||
- mode->handles[0] != mode->handles[2])) {
- ret = -EINVAL;
- goto err;
- }
-
- obj = armada_gem_object_lookup(dev, dfile, mode->handles[0]);
- if (!obj) {
- ret = -ENOENT;
- goto err;
- }
-
- if (obj->obj.import_attach && !obj->sgt) {
- ret = armada_gem_map_import(obj);
- if (ret)
- goto err_unref;
- }
-
- /* Framebuffer objects must have a valid device address for scanout */
- if (obj->dev_addr == DMA_ERROR_CODE) {
- ret = -EINVAL;
- goto err_unref;
- }
-
- dfb = armada_framebuffer_create(dev, mode, obj);
- if (IS_ERR(dfb)) {
- ret = PTR_ERR(dfb);
- goto err;
- }
-
- drm_gem_object_unreference_unlocked(&obj->obj);
-
- return &dfb->fb;
-
- err_unref:
- drm_gem_object_unreference_unlocked(&obj->obj);
- err:
- DRM_ERROR("failed to initialize framebuffer: %d\n", ret);
- return ERR_PTR(ret);
-}
-
-static void armada_output_poll_changed(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
- struct drm_fb_helper *fbh = priv->fbdev;
-
- if (fbh)
- drm_fb_helper_hotplug_event(fbh);
-}
-
-const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
- .fb_create = armada_fb_create,
- .output_poll_changed = armada_output_poll_changed,
-};
diff --git a/drivers/gpu/drm/armada/armada_fb.h b/drivers/gpu/drm/armada/armada_fb.h
deleted file mode 100644
index ce3f12e..0000000
--- a/drivers/gpu/drm/armada/armada_fb.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_FB_H
-#define ARMADA_FB_H
-
-struct armada_framebuffer {
- struct drm_framebuffer fb;
- struct armada_gem_object *obj;
- uint8_t fmt;
- uint8_t mod;
-};
-#define drm_fb_to_armada_fb(dfb) \
- container_of(dfb, struct armada_framebuffer, fb)
-#define drm_fb_obj(fb) drm_fb_to_armada_fb(fb)->obj
-
-struct armada_framebuffer *armada_framebuffer_create(struct drm_device *,
- struct drm_mode_fb_cmd2 *, struct armada_gem_object *);
-
-#endif
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c
deleted file mode 100644
index dd5ea77..0000000
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- * Written from the i915 driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/errno.h>
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
-#include "armada_crtc.h"
-#include "armada_drm.h"
-#include "armada_fb.h"
-#include "armada_gem.h"
-
-static /*const*/ struct fb_ops armada_fb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = drm_fb_helper_check_var,
- .fb_set_par = drm_fb_helper_set_par,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_pan_display = drm_fb_helper_pan_display,
- .fb_blank = drm_fb_helper_blank,
- .fb_setcmap = drm_fb_helper_setcmap,
- .fb_debug_enter = drm_fb_helper_debug_enter,
- .fb_debug_leave = drm_fb_helper_debug_leave,
-};
-
-static int armada_fb_create(struct drm_fb_helper *fbh,
- struct drm_fb_helper_surface_size *sizes)
-{
- struct drm_device *dev = fbh->dev;
- struct drm_mode_fb_cmd2 mode;
- struct armada_framebuffer *dfb;
- struct armada_gem_object *obj;
- struct fb_info *info;
- int size, ret;
- void *ptr;
-
- memset(&mode, 0, sizeof(mode));
- mode.width = sizes->surface_width;
- mode.height = sizes->surface_height;
- mode.pitches[0] = armada_pitch(mode.width, sizes->surface_bpp);
- mode.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
- sizes->surface_depth);
-
- size = mode.pitches[0] * mode.height;
- obj = armada_gem_alloc_private_object(dev, size);
- if (!obj) {
- DRM_ERROR("failed to allocate fb memory\n");
- return -ENOMEM;
- }
-
- ret = armada_gem_linear_back(dev, obj);
- if (ret) {
- drm_gem_object_unreference_unlocked(&obj->obj);
- return ret;
- }
-
- ptr = armada_gem_map_object(dev, obj);
- if (!ptr) {
- drm_gem_object_unreference_unlocked(&obj->obj);
- return -ENOMEM;
- }
-
- dfb = armada_framebuffer_create(dev, &mode, obj);
-
- /*
- * A reference is now held by the framebuffer object if
- * successful, otherwise this drops the ref for the error path.
- */
- drm_gem_object_unreference_unlocked(&obj->obj);
-
- if (IS_ERR(dfb))
- return PTR_ERR(dfb);
-
- info = framebuffer_alloc(0, dev->dev);
- if (!info) {
- ret = -ENOMEM;
- goto err_fballoc;
- }
-
- ret = fb_alloc_cmap(&info->cmap, 256, 0);
- if (ret) {
- ret = -ENOMEM;
- goto err_fbcmap;
- }
-
- strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id));
- info->par = fbh;
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
- info->fbops = &armada_fb_ops;
- info->fix.smem_start = obj->phys_addr;
- info->fix.smem_len = obj->obj.size;
- info->screen_size = obj->obj.size;
- info->screen_base = ptr;
- fbh->fb = &dfb->fb;
- fbh->fbdev = info;
- drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth);
- drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height);
-
- DRM_DEBUG_KMS("allocated %dx%d %dbpp fb: 0x%08x\n",
- dfb->fb.width, dfb->fb.height,
- dfb->fb.bits_per_pixel, obj->phys_addr);
-
- return 0;
-
- err_fbcmap:
- framebuffer_release(info);
- err_fballoc:
- dfb->fb.funcs->destroy(&dfb->fb);
- return ret;
-}
-
-static int armada_fb_probe(struct drm_fb_helper *fbh,
- struct drm_fb_helper_surface_size *sizes)
-{
- int ret = 0;
-
- if (!fbh->fb) {
- ret = armada_fb_create(fbh, sizes);
- if (ret == 0)
- ret = 1;
- }
- return ret;
-}
-
-static struct drm_fb_helper_funcs armada_fb_helper_funcs = {
- .gamma_set = armada_drm_crtc_gamma_set,
- .gamma_get = armada_drm_crtc_gamma_get,
- .fb_probe = armada_fb_probe,
-};
-
-int armada_fbdev_init(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
- struct drm_fb_helper *fbh;
- int ret;
-
- fbh = devm_kzalloc(dev->dev, sizeof(*fbh), GFP_KERNEL);
- if (!fbh)
- return -ENOMEM;
-
- priv->fbdev = fbh;
-
- fbh->funcs = &armada_fb_helper_funcs;
-
- ret = drm_fb_helper_init(dev, fbh, 1, 1);
- if (ret) {
- DRM_ERROR("failed to initialize drm fb helper\n");
- goto err_fb_helper;
- }
-
- ret = drm_fb_helper_single_add_all_connectors(fbh);
- if (ret) {
- DRM_ERROR("failed to add fb connectors\n");
- goto err_fb_setup;
- }
-
- ret = drm_fb_helper_initial_config(fbh, 32);
- if (ret) {
- DRM_ERROR("failed to set initial config\n");
- goto err_fb_setup;
- }
-
- return 0;
- err_fb_setup:
- drm_fb_helper_fini(fbh);
- err_fb_helper:
- priv->fbdev = NULL;
- return ret;
-}
-
-void armada_fbdev_fini(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
- struct drm_fb_helper *fbh = priv->fbdev;
-
- if (fbh) {
- struct fb_info *info = fbh->fbdev;
-
- if (info) {
- unregister_framebuffer(info);
- if (info->cmap.len)
- fb_dealloc_cmap(&info->cmap);
- framebuffer_release(info);
- }
-
- if (fbh->fb)
- fbh->fb->funcs->destroy(fbh->fb);
-
- drm_fb_helper_fini(fbh);
-
- priv->fbdev = NULL;
- }
-}
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
deleted file mode 100644
index 9f2356b..0000000
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/dma-buf.h>
-#include <linux/dma-mapping.h>
-#include <linux/shmem_fs.h>
-#include <drm/drmP.h>
-#include "armada_drm.h"
-#include "armada_gem.h"
-#include <drm/armada_drm.h>
-#include "armada_ioctlP.h"
-
-static int armada_gem_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- struct armada_gem_object *obj = drm_to_armada_gem(vma->vm_private_data);
- unsigned long addr = (unsigned long)vmf->virtual_address;
- unsigned long pfn = obj->phys_addr >> PAGE_SHIFT;
- int ret;
-
- pfn += (addr - vma->vm_start) >> PAGE_SHIFT;
- ret = vm_insert_pfn(vma, addr, pfn);
-
- switch (ret) {
- case 0:
- case -EBUSY:
- return VM_FAULT_NOPAGE;
- case -ENOMEM:
- return VM_FAULT_OOM;
- default:
- return VM_FAULT_SIGBUS;
- }
-}
-
-const struct vm_operations_struct armada_gem_vm_ops = {
- .fault = armada_gem_vm_fault,
- .open = drm_gem_vm_open,
- .close = drm_gem_vm_close,
-};
-
-static size_t roundup_gem_size(size_t size)
-{
- return roundup(size, PAGE_SIZE);
-}
-
-/* dev->struct_mutex is held here */
-void armada_gem_free_object(struct drm_gem_object *obj)
-{
- struct armada_gem_object *dobj = drm_to_armada_gem(obj);
-
- DRM_DEBUG_DRIVER("release obj %p\n", dobj);
-
- drm_gem_free_mmap_offset(&dobj->obj);
-
- if (dobj->page) {
- /* page backed memory */
- unsigned int order = get_order(dobj->obj.size);
- __free_pages(dobj->page, order);
- } else if (dobj->linear) {
- /* linear backed memory */
- drm_mm_remove_node(dobj->linear);
- kfree(dobj->linear);
- if (dobj->addr)
- iounmap(dobj->addr);
- }
-
- if (dobj->obj.import_attach) {
- /* We only ever display imported data */
- dma_buf_unmap_attachment(dobj->obj.import_attach, dobj->sgt,
- DMA_TO_DEVICE);
- drm_prime_gem_destroy(&dobj->obj, NULL);
- }
-
- drm_gem_object_release(&dobj->obj);
-
- kfree(dobj);
-}
-
-int
-armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
-{
- struct armada_private *priv = dev->dev_private;
- size_t size = obj->obj.size;
-
- if (obj->page || obj->linear)
- return 0;
-
- /*
- * If it is a small allocation (typically cursor, which will
- * be 32x64 or 64x32 ARGB pixels) try to get it from the system.
- * Framebuffers will never be this small (our minimum size for
- * framebuffers is larger than this anyway.) Such objects are
- * only accessed by the CPU so we don't need any special handing
- * here.
- */
- if (size <= 8192) {
- unsigned int order = get_order(size);
- struct page *p = alloc_pages(GFP_KERNEL, order);
-
- if (p) {
- obj->addr = page_address(p);
- obj->phys_addr = page_to_phys(p);
- obj->page = p;
-
- memset(obj->addr, 0, PAGE_ALIGN(size));
- }
- }
-
- /*
- * We could grab something from CMA if it's enabled, but that
- * involves building in a problem:
- *
- * CMA's interface uses dma_alloc_coherent(), which provides us
- * with an CPU virtual address and a device address.
- *
- * The CPU virtual address may be either an address in the kernel
- * direct mapped region (for example, as it would be on x86) or
- * it may be remapped into another part of kernel memory space
- * (eg, as it would be on ARM.) This means virt_to_phys() on the
- * returned virtual address is invalid depending on the architecture
- * implementation.
- *
- * The device address may also not be a physical address; it may
- * be that there is some kind of remapping between the device and
- * system RAM, which makes the use of the device address also
- * unsafe to re-use as a physical address.
- *
- * This makes DRM usage of dma_alloc_coherent() in a generic way
- * at best very questionable and unsafe.
- */
-
- /* Otherwise, grab it from our linear allocation */
- if (!obj->page) {
- struct drm_mm_node *node;
- unsigned align = min_t(unsigned, size, SZ_2M);
- void __iomem *ptr;
- int ret;
-
- node = kzalloc(sizeof(*node), GFP_KERNEL);
- if (!node)
- return -ENOSPC;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_mm_insert_node(&priv->linear, node, size, align,
- DRM_MM_SEARCH_DEFAULT);
- mutex_unlock(&dev->struct_mutex);
- if (ret) {
- kfree(node);
- return ret;
- }
-
- obj->linear = node;
-
- /* Ensure that the memory we're returning is cleared. */
- ptr = ioremap_wc(obj->linear->start, size);
- if (!ptr) {
- mutex_lock(&dev->struct_mutex);
- drm_mm_remove_node(obj->linear);
- mutex_unlock(&dev->struct_mutex);
- kfree(obj->linear);
- obj->linear = NULL;
- return -ENOMEM;
- }
-
- memset_io(ptr, 0, size);
- iounmap(ptr);
-
- obj->phys_addr = obj->linear->start;
- obj->dev_addr = obj->linear->start;
- }
-
- DRM_DEBUG_DRIVER("obj %p phys %#x dev %#x\n",
- obj, obj->phys_addr, obj->dev_addr);
-
- return 0;
-}
-
-void *
-armada_gem_map_object(struct drm_device *dev, struct armada_gem_object *dobj)
-{
- /* only linear objects need to be ioremap'd */
- if (!dobj->addr && dobj->linear)
- dobj->addr = ioremap_wc(dobj->phys_addr, dobj->obj.size);
- return dobj->addr;
-}
-
-struct armada_gem_object *
-armada_gem_alloc_private_object(struct drm_device *dev, size_t size)
-{
- struct armada_gem_object *obj;
-
- size = roundup_gem_size(size);
-
- obj = kzalloc(sizeof(*obj), GFP_KERNEL);
- if (!obj)
- return NULL;
-
- drm_gem_private_object_init(dev, &obj->obj, size);
- obj->dev_addr = DMA_ERROR_CODE;
-
- DRM_DEBUG_DRIVER("alloc private obj %p size %zu\n", obj, size);
-
- return obj;
-}
-
-struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev,
- size_t size)
-{
- struct armada_gem_object *obj;
- struct address_space *mapping;
-
- size = roundup_gem_size(size);
-
- obj = kzalloc(sizeof(*obj), GFP_KERNEL);
- if (!obj)
- return NULL;
-
- if (drm_gem_object_init(dev, &obj->obj, size)) {
- kfree(obj);
- return NULL;
- }
-
- obj->dev_addr = DMA_ERROR_CODE;
-
- mapping = obj->obj.filp->f_path.dentry->d_inode->i_mapping;
- mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE);
-
- DRM_DEBUG_DRIVER("alloc obj %p size %zu\n", obj, size);
-
- return obj;
-}
-
-/* Dumb alloc support */
-int armada_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
- struct drm_mode_create_dumb *args)
-{
- struct armada_gem_object *dobj;
- u32 handle;
- size_t size;
- int ret;
-
- args->pitch = armada_pitch(args->width, args->bpp);
- args->size = size = args->pitch * args->height;
-
- dobj = armada_gem_alloc_private_object(dev, size);
- if (dobj == NULL)
- return -ENOMEM;
-
- ret = armada_gem_linear_back(dev, dobj);
- if (ret)
- goto err;
-
- ret = drm_gem_handle_create(file, &dobj->obj, &handle);
- if (ret)
- goto err;
-
- args->handle = handle;
-
- /* drop reference from allocate - handle holds it now */
- DRM_DEBUG_DRIVER("obj %p size %zu handle %#x\n", dobj, size, handle);
- err:
- drm_gem_object_unreference_unlocked(&dobj->obj);
- return ret;
-}
-
-int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
- uint32_t handle, uint64_t *offset)
-{
- struct armada_gem_object *obj;
- int ret = 0;
-
- mutex_lock(&dev->struct_mutex);
- obj = armada_gem_object_lookup(dev, file, handle);
- if (!obj) {
- DRM_ERROR("failed to lookup gem object\n");
- ret = -EINVAL;
- goto err_unlock;
- }
-
- /* Don't allow imported objects to be mapped */
- if (obj->obj.import_attach) {
- ret = -EINVAL;
- goto err_unlock;
- }
-
- ret = drm_gem_create_mmap_offset(&obj->obj);
- if (ret == 0) {
- *offset = drm_vma_node_offset_addr(&obj->obj.vma_node);
- DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset);
- }
-
- drm_gem_object_unreference(&obj->obj);
- err_unlock:
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
-
-int armada_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
- uint32_t handle)
-{
- return drm_gem_handle_delete(file, handle);
-}
-
-/* Private driver gem ioctls */
-int armada_gem_create_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_armada_gem_create *args = data;
- struct armada_gem_object *dobj;
- size_t size;
- u32 handle;
- int ret;
-
- if (args->size == 0)
- return -ENOMEM;
-
- size = args->size;
-
- dobj = armada_gem_alloc_object(dev, size);
- if (dobj == NULL)
- return -ENOMEM;
-
- ret = drm_gem_handle_create(file, &dobj->obj, &handle);
- if (ret)
- goto err;
-
- args->handle = handle;
-
- /* drop reference from allocate - handle holds it now */
- DRM_DEBUG_DRIVER("obj %p size %zu handle %#x\n", dobj, size, handle);
- err:
- drm_gem_object_unreference_unlocked(&dobj->obj);
- return ret;
-}
-
-/* Map a shmem-backed object into process memory space */
-int armada_gem_mmap_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_armada_gem_mmap *args = data;
- struct armada_gem_object *dobj;
- unsigned long addr;
-
- dobj = armada_gem_object_lookup(dev, file, args->handle);
- if (dobj == NULL)
- return -ENOENT;
-
- if (!dobj->obj.filp) {
- drm_gem_object_unreference(&dobj->obj);
- return -EINVAL;
- }
-
- addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE,
- MAP_SHARED, args->offset);
- drm_gem_object_unreference(&dobj->obj);
- if (IS_ERR_VALUE(addr))
- return addr;
-
- args->addr = addr;
-
- return 0;
-}
-
-int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_armada_gem_pwrite *args = data;
- struct armada_gem_object *dobj;
- char __user *ptr;
- int ret;
-
- DRM_DEBUG_DRIVER("handle %u off %u size %u ptr 0x%llx\n",
- args->handle, args->offset, args->size, args->ptr);
-
- if (args->size == 0)
- return 0;
-
- ptr = (char __user *)(uintptr_t)args->ptr;
-
- if (!access_ok(VERIFY_READ, ptr, args->size))
- return -EFAULT;
-
- ret = fault_in_multipages_readable(ptr, args->size);
- if (ret)
- return ret;
-
- dobj = armada_gem_object_lookup(dev, file, args->handle);
- if (dobj == NULL)
- return -ENOENT;
-
- /* Must be a kernel-mapped object */
- if (!dobj->addr)
- return -EINVAL;
-
- if (args->offset > dobj->obj.size ||
- args->size > dobj->obj.size - args->offset) {
- DRM_ERROR("invalid size: object size %u\n", dobj->obj.size);
- ret = -EINVAL;
- goto unref;
- }
-
- if (copy_from_user(dobj->addr + args->offset, ptr, args->size)) {
- ret = -EFAULT;
- } else if (dobj->update) {
- dobj->update(dobj->update_data);
- ret = 0;
- }
-
- unref:
- drm_gem_object_unreference_unlocked(&dobj->obj);
- return ret;
-}
-
-/* Prime support */
-struct sg_table *
-armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
- enum dma_data_direction dir)
-{
- struct drm_gem_object *obj = attach->dmabuf->priv;
- struct armada_gem_object *dobj = drm_to_armada_gem(obj);
- struct scatterlist *sg;
- struct sg_table *sgt;
- int i, num;
-
- sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
- if (!sgt)
- return NULL;
-
- if (dobj->obj.filp) {
- struct address_space *mapping;
- gfp_t gfp;
- int count;
-
- count = dobj->obj.size / PAGE_SIZE;
- if (sg_alloc_table(sgt, count, GFP_KERNEL))
- goto free_sgt;
-
- mapping = file_inode(dobj->obj.filp)->i_mapping;
- gfp = mapping_gfp_mask(mapping);
-
- for_each_sg(sgt->sgl, sg, count, i) {
- struct page *page;
-
- page = shmem_read_mapping_page_gfp(mapping, i, gfp);
- if (IS_ERR(page)) {
- num = i;
- goto release;
- }
-
- sg_set_page(sg, page, PAGE_SIZE, 0);
- }
-
- if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) {
- num = sgt->nents;
- goto release;
- }
- } else if (dobj->page) {
- /* Single contiguous page */
- if (sg_alloc_table(sgt, 1, GFP_KERNEL))
- goto free_sgt;
-
- sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
-
- if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
- goto free_table;
- } else if (dobj->linear) {
- /* Single contiguous physical region - no struct page */
- if (sg_alloc_table(sgt, 1, GFP_KERNEL))
- goto free_sgt;
- sg_dma_address(sgt->sgl) = dobj->dev_addr;
- sg_dma_len(sgt->sgl) = dobj->obj.size;
- } else {
- goto free_sgt;
- }
- return sgt;
-
- release:
- for_each_sg(sgt->sgl, sg, num, i)
- page_cache_release(sg_page(sg));
- free_table:
- sg_free_table(sgt);
- free_sgt:
- kfree(sgt);
- return NULL;
-}
-
-static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
- struct sg_table *sgt, enum dma_data_direction dir)
-{
- struct drm_gem_object *obj = attach->dmabuf->priv;
- struct armada_gem_object *dobj = drm_to_armada_gem(obj);
- int i;
-
- if (!dobj->linear)
- dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
-
- if (dobj->obj.filp) {
- struct scatterlist *sg;
- for_each_sg(sgt->sgl, sg, sgt->nents, i)
- page_cache_release(sg_page(sg));
- }
-
- sg_free_table(sgt);
- kfree(sgt);
-}
-
-static void *armada_gem_dmabuf_no_kmap(struct dma_buf *buf, unsigned long n)
-{
- return NULL;
-}
-
-static void
-armada_gem_dmabuf_no_kunmap(struct dma_buf *buf, unsigned long n, void *addr)
-{
-}
-
-static int
-armada_gem_dmabuf_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
-{
- return -EINVAL;
-}
-
-static const struct dma_buf_ops armada_gem_prime_dmabuf_ops = {
- .map_dma_buf = armada_gem_prime_map_dma_buf,
- .unmap_dma_buf = armada_gem_prime_unmap_dma_buf,
- .release = drm_gem_dmabuf_release,
- .kmap_atomic = armada_gem_dmabuf_no_kmap,
- .kunmap_atomic = armada_gem_dmabuf_no_kunmap,
- .kmap = armada_gem_dmabuf_no_kmap,
- .kunmap = armada_gem_dmabuf_no_kunmap,
- .mmap = armada_gem_dmabuf_mmap,
-};
-
-struct dma_buf *
-armada_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj,
- int flags)
-{
- return dma_buf_export(obj, &armada_gem_prime_dmabuf_ops, obj->size,
- O_RDWR);
-}
-
-struct drm_gem_object *
-armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
-{
- struct dma_buf_attachment *attach;
- struct armada_gem_object *dobj;
-
- if (buf->ops == &armada_gem_prime_dmabuf_ops) {
- struct drm_gem_object *obj = buf->priv;
- if (obj->dev == dev) {
- /*
- * Importing our own dmabuf(s) increases the
- * refcount on the gem object itself.
- */
- drm_gem_object_reference(obj);
- dma_buf_put(buf);
- return obj;
- }
- }
-
- attach = dma_buf_attach(buf, dev->dev);
- if (IS_ERR(attach))
- return ERR_CAST(attach);
-
- dobj = armada_gem_alloc_private_object(dev, buf->size);
- if (!dobj) {
- dma_buf_detach(buf, attach);
- return ERR_PTR(-ENOMEM);
- }
-
- dobj->obj.import_attach = attach;
-
- /*
- * Don't call dma_buf_map_attachment() here - it maps the
- * scatterlist immediately for DMA, and this is not always
- * an appropriate thing to do.
- */
- return &dobj->obj;
-}
-
-int armada_gem_map_import(struct armada_gem_object *dobj)
-{
- int ret;
-
- dobj->sgt = dma_buf_map_attachment(dobj->obj.import_attach,
- DMA_TO_DEVICE);
- if (!dobj->sgt) {
- DRM_ERROR("dma_buf_map_attachment() returned NULL\n");
- return -EINVAL;
- }
- if (IS_ERR(dobj->sgt)) {
- ret = PTR_ERR(dobj->sgt);
- dobj->sgt = NULL;
- DRM_ERROR("dma_buf_map_attachment() error: %d\n", ret);
- return ret;
- }
- if (dobj->sgt->nents > 1) {
- DRM_ERROR("dma_buf_map_attachment() returned an (unsupported) scattered list\n");
- return -EINVAL;
- }
- if (sg_dma_len(dobj->sgt->sgl) < dobj->obj.size) {
- DRM_ERROR("dma_buf_map_attachment() returned a small buffer\n");
- return -EINVAL;
- }
- dobj->dev_addr = sg_dma_address(dobj->sgt->sgl);
- return 0;
-}
diff --git a/drivers/gpu/drm/armada/armada_gem.h b/drivers/gpu/drm/armada/armada_gem.h
deleted file mode 100644
index 00b6cd4..0000000
--- a/drivers/gpu/drm/armada/armada_gem.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_GEM_H
-#define ARMADA_GEM_H
-
-/* GEM */
-struct armada_gem_object {
- struct drm_gem_object obj;
- void *addr;
- phys_addr_t phys_addr;
- resource_size_t dev_addr;
- struct drm_mm_node *linear; /* for linear backed */
- struct page *page; /* for page backed */
- struct sg_table *sgt; /* for imported */
- void (*update)(void *);
- void *update_data;
-};
-
-extern const struct vm_operations_struct armada_gem_vm_ops;
-
-#define drm_to_armada_gem(o) container_of(o, struct armada_gem_object, obj)
-
-void armada_gem_free_object(struct drm_gem_object *);
-int armada_gem_linear_back(struct drm_device *, struct armada_gem_object *);
-void *armada_gem_map_object(struct drm_device *, struct armada_gem_object *);
-struct armada_gem_object *armada_gem_alloc_private_object(struct drm_device *,
- size_t);
-int armada_gem_dumb_create(struct drm_file *, struct drm_device *,
- struct drm_mode_create_dumb *);
-int armada_gem_dumb_map_offset(struct drm_file *, struct drm_device *,
- uint32_t, uint64_t *);
-int armada_gem_dumb_destroy(struct drm_file *, struct drm_device *,
- uint32_t);
-struct dma_buf *armada_gem_prime_export(struct drm_device *dev,
- struct drm_gem_object *obj, int flags);
-struct drm_gem_object *armada_gem_prime_import(struct drm_device *,
- struct dma_buf *);
-int armada_gem_map_import(struct armada_gem_object *);
-
-static inline struct armada_gem_object *armada_gem_object_lookup(
- struct drm_device *dev, struct drm_file *dfile, unsigned handle)
-{
- struct drm_gem_object *obj = drm_gem_object_lookup(dev, dfile, handle);
-
- return obj ? drm_to_armada_gem(obj) : NULL;
-}
-#endif
diff --git a/drivers/gpu/drm/armada/armada_hw.h b/drivers/gpu/drm/armada/armada_hw.h
deleted file mode 100644
index 27319a8..0000000
--- a/drivers/gpu/drm/armada/armada_hw.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- * Rewritten from the dovefb driver, and Armada510 manuals.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_HW_H
-#define ARMADA_HW_H
-
-/*
- * Note: the following registers are written from IRQ context:
- * LCD_SPU_V_PORCH, LCD_SPU_ADV_REG, LCD_SPUT_V_H_TOTAL
- * LCD_SPU_DMA_START_ADDR_[YUV][01], LCD_SPU_DMA_PITCH_YC,
- * LCD_SPU_DMA_PITCH_UV, LCD_SPU_DMA_OVSA_HPXL_VLN,
- * LCD_SPU_DMA_HPXL_VLN, LCD_SPU_DZM_HPXL_VLN, LCD_SPU_DMA_CTRL0
- */
-enum {
- LCD_SPU_ADV_REG = 0x0084, /* Armada 510 */
- LCD_SPU_DMA_START_ADDR_Y0 = 0x00c0,
- LCD_SPU_DMA_START_ADDR_U0 = 0x00c4,
- LCD_SPU_DMA_START_ADDR_V0 = 0x00c8,
- LCD_CFG_DMA_START_ADDR_0 = 0x00cc,
- LCD_SPU_DMA_START_ADDR_Y1 = 0x00d0,
- LCD_SPU_DMA_START_ADDR_U1 = 0x00d4,
- LCD_SPU_DMA_START_ADDR_V1 = 0x00d8,
- LCD_CFG_DMA_START_ADDR_1 = 0x00dc,
- LCD_SPU_DMA_PITCH_YC = 0x00e0,
- LCD_SPU_DMA_PITCH_UV = 0x00e4,
- LCD_SPU_DMA_OVSA_HPXL_VLN = 0x00e8,
- LCD_SPU_DMA_HPXL_VLN = 0x00ec,
- LCD_SPU_DZM_HPXL_VLN = 0x00f0,
- LCD_CFG_GRA_START_ADDR0 = 0x00f4,
- LCD_CFG_GRA_START_ADDR1 = 0x00f8,
- LCD_CFG_GRA_PITCH = 0x00fc,
- LCD_SPU_GRA_OVSA_HPXL_VLN = 0x0100,
- LCD_SPU_GRA_HPXL_VLN = 0x0104,
- LCD_SPU_GZM_HPXL_VLN = 0x0108,
- LCD_SPU_HWC_OVSA_HPXL_VLN = 0x010c,
- LCD_SPU_HWC_HPXL_VLN = 0x0110,
- LCD_SPUT_V_H_TOTAL = 0x0114,
- LCD_SPU_V_H_ACTIVE = 0x0118,
- LCD_SPU_H_PORCH = 0x011c,
- LCD_SPU_V_PORCH = 0x0120,
- LCD_SPU_BLANKCOLOR = 0x0124,
- LCD_SPU_ALPHA_COLOR1 = 0x0128,
- LCD_SPU_ALPHA_COLOR2 = 0x012c,
- LCD_SPU_COLORKEY_Y = 0x0130,
- LCD_SPU_COLORKEY_U = 0x0134,
- LCD_SPU_COLORKEY_V = 0x0138,
- LCD_CFG_RDREG4F = 0x013c, /* Armada 510 */
- LCD_SPU_SPI_RXDATA = 0x0140,
- LCD_SPU_ISA_RXDATA = 0x0144,
- LCD_SPU_HWC_RDDAT = 0x0158,
- LCD_SPU_GAMMA_RDDAT = 0x015c,
- LCD_SPU_PALETTE_RDDAT = 0x0160,
- LCD_SPU_IOPAD_IN = 0x0178,
- LCD_CFG_RDREG5F = 0x017c,
- LCD_SPU_SPI_CTRL = 0x0180,
- LCD_SPU_SPI_TXDATA = 0x0184,
- LCD_SPU_SMPN_CTRL = 0x0188,
- LCD_SPU_DMA_CTRL0 = 0x0190,
- LCD_SPU_DMA_CTRL1 = 0x0194,
- LCD_SPU_SRAM_CTRL = 0x0198,
- LCD_SPU_SRAM_WRDAT = 0x019c,
- LCD_SPU_SRAM_PARA0 = 0x01a0, /* Armada 510 */
- LCD_SPU_SRAM_PARA1 = 0x01a4,
- LCD_CFG_SCLK_DIV = 0x01a8,
- LCD_SPU_CONTRAST = 0x01ac,
- LCD_SPU_SATURATION = 0x01b0,
- LCD_SPU_CBSH_HUE = 0x01b4,
- LCD_SPU_DUMB_CTRL = 0x01b8,
- LCD_SPU_IOPAD_CONTROL = 0x01bc,
- LCD_SPU_IRQ_ENA = 0x01c0,
- LCD_SPU_IRQ_ISR = 0x01c4,
-};
-
-/* For LCD_SPU_ADV_REG */
-enum {
- ADV_VSYNC_L_OFF = 0xfff << 20,
- ADV_GRACOLORKEY = 1 << 19,
- ADV_VIDCOLORKEY = 1 << 18,
- ADV_HWC32BLEND = 1 << 15,
- ADV_HWC32ARGB = 1 << 14,
- ADV_HWC32ENABLE = 1 << 13,
- ADV_VSYNCOFFEN = 1 << 12,
- ADV_VSYNC_H_OFF = 0xfff << 0,
-};
-
-enum {
- CFG_565 = 0,
- CFG_1555 = 1,
- CFG_888PACK = 2,
- CFG_X888 = 3,
- CFG_8888 = 4,
- CFG_422PACK = 5,
- CFG_422 = 6,
- CFG_420 = 7,
- CFG_PSEUDO4 = 9,
- CFG_PSEUDO8 = 10,
- CFG_SWAPRB = 1 << 4,
- CFG_SWAPUV = 1 << 3,
- CFG_SWAPYU = 1 << 2,
- CFG_YUV2RGB = 1 << 1,
-};
-
-/* For LCD_SPU_DMA_CTRL0 */
-enum {
- CFG_NOBLENDING = 1 << 31,
- CFG_GAMMA_ENA = 1 << 30,
- CFG_CBSH_ENA = 1 << 29,
- CFG_PALETTE_ENA = 1 << 28,
- CFG_ARBFAST_ENA = 1 << 27,
- CFG_HWC_1BITMOD = 1 << 26,
- CFG_HWC_1BITENA = 1 << 25,
- CFG_HWC_ENA = 1 << 24,
- CFG_DMAFORMAT = 0xf << 20,
-#define CFG_DMA_FMT(x) ((x) << 20)
- CFG_GRAFORMAT = 0xf << 16,
-#define CFG_GRA_FMT(x) ((x) << 16)
-#define CFG_GRA_MOD(x) ((x) << 8)
- CFG_GRA_FTOGGLE = 1 << 15,
- CFG_GRA_HSMOOTH = 1 << 14,
- CFG_GRA_TSTMODE = 1 << 13,
- CFG_GRA_ENA = 1 << 8,
-#define CFG_DMA_MOD(x) ((x) << 0)
- CFG_DMA_FTOGGLE = 1 << 7,
- CFG_DMA_HSMOOTH = 1 << 6,
- CFG_DMA_TSTMODE = 1 << 5,
- CFG_DMA_ENA = 1 << 0,
-};
-
-enum {
- CKMODE_DISABLE = 0,
- CKMODE_Y = 1,
- CKMODE_U = 2,
- CKMODE_RGB = 3,
- CKMODE_V = 4,
- CKMODE_R = 5,
- CKMODE_G = 6,
- CKMODE_B = 7,
-};
-
-/* For LCD_SPU_DMA_CTRL1 */
-enum {
- CFG_FRAME_TRIG = 1 << 31,
- CFG_VSYNC_INV = 1 << 27,
- CFG_CKMODE_MASK = 0x7 << 24,
-#define CFG_CKMODE(x) ((x) << 24)
- CFG_CARRY = 1 << 23,
- CFG_GATED_CLK = 1 << 21,
- CFG_PWRDN_ENA = 1 << 20,
- CFG_DSCALE_MASK = 0x3 << 18,
- CFG_DSCALE_NONE = 0x0 << 18,
- CFG_DSCALE_HALF = 0x1 << 18,
- CFG_DSCALE_QUAR = 0x2 << 18,
- CFG_ALPHAM_MASK = 0x3 << 16,
- CFG_ALPHAM_VIDEO = 0x0 << 16,
- CFG_ALPHAM_GRA = 0x1 << 16,
- CFG_ALPHAM_CFG = 0x2 << 16,
- CFG_ALPHA_MASK = 0xff << 8,
- CFG_PIXCMD_MASK = 0xff,
-};
-
-/* For LCD_SPU_SRAM_CTRL */
-enum {
- SRAM_READ = 0 << 14,
- SRAM_WRITE = 2 << 14,
- SRAM_INIT = 3 << 14,
- SRAM_HWC32_RAM1 = 0xc << 8,
- SRAM_HWC32_RAM2 = 0xd << 8,
- SRAM_HWC32_RAMR = SRAM_HWC32_RAM1,
- SRAM_HWC32_RAMG = SRAM_HWC32_RAM2,
- SRAM_HWC32_RAMB = 0xe << 8,
- SRAM_HWC32_TRAN = 0xf << 8,
- SRAM_HWC = 0xf << 8,
-};
-
-/* For LCD_SPU_SRAM_PARA1 */
-enum {
- CFG_CSB_256x32 = 1 << 15, /* cursor */
- CFG_CSB_256x24 = 1 << 14, /* palette */
- CFG_CSB_256x8 = 1 << 13, /* gamma */
- CFG_PDWN1920x32 = 1 << 8, /* Armada 510: power down vscale ram */
- CFG_PDWN256x32 = 1 << 7, /* power down cursor */
- CFG_PDWN256x24 = 1 << 6, /* power down palette */
- CFG_PDWN256x8 = 1 << 5, /* power down gamma */
- CFG_PDWNHWC = 1 << 4, /* Armada 510: power down all hwc ram */
- CFG_PDWN32x32 = 1 << 3, /* power down slave->smart ram */
- CFG_PDWN16x66 = 1 << 2, /* power down UV fifo */
- CFG_PDWN32x66 = 1 << 1, /* power down Y fifo */
- CFG_PDWN64x66 = 1 << 0, /* power down graphic fifo */
-};
-
-/* For LCD_CFG_SCLK_DIV */
-enum {
- /* Armada 510 */
- SCLK_510_AXI = 0x0 << 30,
- SCLK_510_EXTCLK0 = 0x1 << 30,
- SCLK_510_PLL = 0x2 << 30,
- SCLK_510_EXTCLK1 = 0x3 << 30,
- SCLK_510_DIV_CHANGE = 1 << 29,
- SCLK_510_FRAC_DIV_MASK = 0xfff << 16,
- SCLK_510_INT_DIV_MASK = 0xffff << 0,
-
- /* Armada 16x */
- SCLK_16X_AHB = 0x0 << 28,
- SCLK_16X_PCLK = 0x1 << 28,
- SCLK_16X_AXI = 0x4 << 28,
- SCLK_16X_PLL = 0x8 << 28,
- SCLK_16X_FRAC_DIV_MASK = 0xfff << 16,
- SCLK_16X_INT_DIV_MASK = 0xffff << 0,
-};
-
-/* For LCD_SPU_DUMB_CTRL */
-enum {
- DUMB16_RGB565_0 = 0x0 << 28,
- DUMB16_RGB565_1 = 0x1 << 28,
- DUMB18_RGB666_0 = 0x2 << 28,
- DUMB18_RGB666_1 = 0x3 << 28,
- DUMB12_RGB444_0 = 0x4 << 28,
- DUMB12_RGB444_1 = 0x5 << 28,
- DUMB24_RGB888_0 = 0x6 << 28,
- DUMB_BLANK = 0x7 << 28,
- DUMB_MASK = 0xf << 28,
- CFG_BIAS_OUT = 1 << 8,
- CFG_REV_RGB = 1 << 7,
- CFG_INV_CBLANK = 1 << 6,
- CFG_INV_CSYNC = 1 << 5, /* Normally active high */
- CFG_INV_HENA = 1 << 4,
- CFG_INV_VSYNC = 1 << 3, /* Normally active high */
- CFG_INV_HSYNC = 1 << 2, /* Normally active high */
- CFG_INV_PCLK = 1 << 1,
- CFG_DUMB_ENA = 1 << 0,
-};
-
-/* For LCD_SPU_IOPAD_CONTROL */
-enum {
- CFG_VSCALE_LN_EN = 3 << 18,
- CFG_GRA_VM_ENA = 1 << 15,
- CFG_DMA_VM_ENA = 1 << 13,
- CFG_CMD_VM_ENA = 1 << 11,
- CFG_CSC_MASK = 3 << 8,
- CFG_CSC_YUV_CCIR709 = 1 << 9,
- CFG_CSC_YUV_CCIR601 = 0 << 9,
- CFG_CSC_RGB_STUDIO = 1 << 8,
- CFG_CSC_RGB_COMPUTER = 0 << 8,
- CFG_IOPAD_MASK = 0xf << 0,
- CFG_IOPAD_DUMB24 = 0x0 << 0,
- CFG_IOPAD_DUMB18SPI = 0x1 << 0,
- CFG_IOPAD_DUMB18GPIO = 0x2 << 0,
- CFG_IOPAD_DUMB16SPI = 0x3 << 0,
- CFG_IOPAD_DUMB16GPIO = 0x4 << 0,
- CFG_IOPAD_DUMB12GPIO = 0x5 << 0,
- CFG_IOPAD_SMART18 = 0x6 << 0,
- CFG_IOPAD_SMART16 = 0x7 << 0,
- CFG_IOPAD_SMART8 = 0x8 << 0,
-};
-
-#define IOPAD_DUMB24 0x0
-
-/* For LCD_SPU_IRQ_ENA */
-enum {
- DMA_FRAME_IRQ0_ENA = 1 << 31,
- DMA_FRAME_IRQ1_ENA = 1 << 30,
- DMA_FRAME_IRQ_ENA = DMA_FRAME_IRQ0_ENA | DMA_FRAME_IRQ1_ENA,
- DMA_FF_UNDERFLOW_ENA = 1 << 29,
- GRA_FRAME_IRQ0_ENA = 1 << 27,
- GRA_FRAME_IRQ1_ENA = 1 << 26,
- GRA_FRAME_IRQ_ENA = GRA_FRAME_IRQ0_ENA | GRA_FRAME_IRQ1_ENA,
- GRA_FF_UNDERFLOW_ENA = 1 << 25,
- VSYNC_IRQ_ENA = 1 << 23,
- DUMB_FRAMEDONE_ENA = 1 << 22,
- TWC_FRAMEDONE_ENA = 1 << 21,
- HWC_FRAMEDONE_ENA = 1 << 20,
- SLV_IRQ_ENA = 1 << 19,
- SPI_IRQ_ENA = 1 << 18,
- PWRDN_IRQ_ENA = 1 << 17,
- ERR_IRQ_ENA = 1 << 16,
- CLEAN_SPU_IRQ_ISR = 0xffff,
-};
-
-/* For LCD_SPU_IRQ_ISR */
-enum {
- DMA_FRAME_IRQ0 = 1 << 31,
- DMA_FRAME_IRQ1 = 1 << 30,
- DMA_FRAME_IRQ = DMA_FRAME_IRQ0 | DMA_FRAME_IRQ1,
- DMA_FF_UNDERFLOW = 1 << 29,
- GRA_FRAME_IRQ0 = 1 << 27,
- GRA_FRAME_IRQ1 = 1 << 26,
- GRA_FRAME_IRQ = GRA_FRAME_IRQ0 | GRA_FRAME_IRQ1,
- GRA_FF_UNDERFLOW = 1 << 25,
- VSYNC_IRQ = 1 << 23,
- DUMB_FRAMEDONE = 1 << 22,
- TWC_FRAMEDONE = 1 << 21,
- HWC_FRAMEDONE = 1 << 20,
- SLV_IRQ = 1 << 19,
- SPI_IRQ = 1 << 18,
- PWRDN_IRQ = 1 << 17,
- ERR_IRQ = 1 << 16,
- DMA_FRAME_IRQ0_LEVEL = 1 << 15,
- DMA_FRAME_IRQ1_LEVEL = 1 << 14,
- DMA_FRAME_CNT_ISR = 3 << 12,
- GRA_FRAME_IRQ0_LEVEL = 1 << 11,
- GRA_FRAME_IRQ1_LEVEL = 1 << 10,
- GRA_FRAME_CNT_ISR = 3 << 8,
- VSYNC_IRQ_LEVEL = 1 << 7,
- DUMB_FRAMEDONE_LEVEL = 1 << 6,
- TWC_FRAMEDONE_LEVEL = 1 << 5,
- HWC_FRAMEDONE_LEVEL = 1 << 4,
- SLV_FF_EMPTY = 1 << 3,
- DMA_FF_ALLEMPTY = 1 << 2,
- GRA_FF_ALLEMPTY = 1 << 1,
- PWRDN_IRQ_LEVEL = 1 << 0,
-};
-
-#endif
diff --git a/drivers/gpu/drm/armada/armada_ioctlP.h b/drivers/gpu/drm/armada/armada_ioctlP.h
deleted file mode 100644
index bd8c456..0000000
--- a/drivers/gpu/drm/armada/armada_ioctlP.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_IOCTLP_H
-#define ARMADA_IOCTLP_H
-
-#define ARMADA_IOCTL_PROTO(name)\
-extern int armada_##name##_ioctl(struct drm_device *, void *, struct drm_file *)
-
-ARMADA_IOCTL_PROTO(gem_create);
-ARMADA_IOCTL_PROTO(gem_mmap);
-ARMADA_IOCTL_PROTO(gem_pwrite);
-
-#endif
diff --git a/drivers/gpu/drm/armada/armada_output.c b/drivers/gpu/drm/armada/armada_output.c
deleted file mode 100644
index d685a54..0000000
--- a/drivers/gpu/drm/armada/armada_output.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
-#include "armada_output.h"
-#include "armada_drm.h"
-
-struct armada_connector {
- struct drm_connector conn;
- const struct armada_output_type *type;
-};
-
-#define drm_to_armada_conn(c) container_of(c, struct armada_connector, conn)
-
-struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn)
-{
- struct drm_encoder *enc = conn->encoder;
-
- return enc ? enc : drm_encoder_find(conn->dev, conn->encoder_ids[0]);
-}
-
-static enum drm_connector_status armada_drm_connector_detect(
- struct drm_connector *conn, bool force)
-{
- struct armada_connector *dconn = drm_to_armada_conn(conn);
- enum drm_connector_status status = connector_status_disconnected;
-
- if (dconn->type->detect) {
- status = dconn->type->detect(conn, force);
- } else {
- struct drm_encoder *enc = armada_drm_connector_encoder(conn);
-
- if (enc)
- status = encoder_helper_funcs(enc)->detect(enc, conn);
- }
-
- return status;
-}
-
-static void armada_drm_connector_destroy(struct drm_connector *conn)
-{
- struct armada_connector *dconn = drm_to_armada_conn(conn);
-
- drm_sysfs_connector_remove(conn);
- drm_connector_cleanup(conn);
- kfree(dconn);
-}
-
-static int armada_drm_connector_set_property(struct drm_connector *conn,
- struct drm_property *property, uint64_t value)
-{
- struct armada_connector *dconn = drm_to_armada_conn(conn);
-
- if (!dconn->type->set_property)
- return -EINVAL;
-
- return dconn->type->set_property(conn, property, value);
-}
-
-static const struct drm_connector_funcs armada_drm_conn_funcs = {
- .dpms = drm_helper_connector_dpms,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .detect = armada_drm_connector_detect,
- .destroy = armada_drm_connector_destroy,
- .set_property = armada_drm_connector_set_property,
-};
-
-void armada_drm_encoder_prepare(struct drm_encoder *encoder)
-{
- encoder_helper_funcs(encoder)->dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-void armada_drm_encoder_commit(struct drm_encoder *encoder)
-{
- encoder_helper_funcs(encoder)->dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-bool armada_drm_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode, struct drm_display_mode *adjusted)
-{
- return true;
-}
-
-/* Shouldn't this be a generic helper function? */
-int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
- struct drm_display_mode *mode)
-{
- struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
- int valid = MODE_BAD;
-
- if (encoder) {
- struct drm_encoder_slave *slave = to_encoder_slave(encoder);
-
- valid = slave->slave_funcs->mode_valid(encoder, mode);
- }
- return valid;
-}
-
-int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
- struct drm_property *property, uint64_t value)
-{
- struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
- int rc = -EINVAL;
-
- if (encoder) {
- struct drm_encoder_slave *slave = to_encoder_slave(encoder);
-
- rc = slave->slave_funcs->set_property(encoder, conn, property,
- value);
- }
- return rc;
-}
-
-int armada_output_create(struct drm_device *dev,
- const struct armada_output_type *type, const void *data)
-{
- struct armada_connector *dconn;
- int ret;
-
- dconn = kzalloc(sizeof(*dconn), GFP_KERNEL);
- if (!dconn)
- return -ENOMEM;
-
- dconn->type = type;
-
- ret = drm_connector_init(dev, &dconn->conn, &armada_drm_conn_funcs,
- type->connector_type);
- if (ret) {
- DRM_ERROR("unable to init connector\n");
- goto err_destroy_dconn;
- }
-
- ret = type->create(&dconn->conn, data);
- if (ret)
- goto err_conn;
-
- ret = drm_sysfs_connector_add(&dconn->conn);
- if (ret)
- goto err_sysfs;
-
- return 0;
-
- err_sysfs:
- if (dconn->conn.encoder)
- dconn->conn.encoder->funcs->destroy(dconn->conn.encoder);
- err_conn:
- drm_connector_cleanup(&dconn->conn);
- err_destroy_dconn:
- kfree(dconn);
- return ret;
-}
diff --git a/drivers/gpu/drm/armada/armada_output.h b/drivers/gpu/drm/armada/armada_output.h
deleted file mode 100644
index 4126d43..0000000
--- a/drivers/gpu/drm/armada/armada_output.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_CONNETOR_H
-#define ARMADA_CONNETOR_H
-
-#define encoder_helper_funcs(encoder) \
- ((struct drm_encoder_helper_funcs *)encoder->helper_private)
-
-struct armada_output_type {
- int connector_type;
- enum drm_connector_status (*detect)(struct drm_connector *, bool);
- int (*create)(struct drm_connector *, const void *);
- int (*set_property)(struct drm_connector *, struct drm_property *,
- uint64_t);
-};
-
-struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn);
-
-void armada_drm_encoder_prepare(struct drm_encoder *encoder);
-void armada_drm_encoder_commit(struct drm_encoder *encoder);
-
-bool armada_drm_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode, struct drm_display_mode *adj);
-
-int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
- struct drm_display_mode *mode);
-
-int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
- struct drm_property *property, uint64_t value);
-
-int armada_output_create(struct drm_device *dev,
- const struct armada_output_type *type, const void *data);
-
-#endif
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
deleted file mode 100644
index c5b06fd..0000000
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- * Rewritten from the dovefb driver, and Armada510 manuals.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <drm/drmP.h>
-#include "armada_crtc.h"
-#include "armada_drm.h"
-#include "armada_fb.h"
-#include "armada_gem.h"
-#include "armada_hw.h"
-#include <drm/armada_drm.h>
-#include "armada_ioctlP.h"
-
-struct armada_plane_properties {
- uint32_t colorkey_yr;
- uint32_t colorkey_ug;
- uint32_t colorkey_vb;
-#define K2R(val) (((val) >> 0) & 0xff)
-#define K2G(val) (((val) >> 8) & 0xff)
-#define K2B(val) (((val) >> 16) & 0xff)
- int16_t brightness;
- uint16_t contrast;
- uint16_t saturation;
- uint32_t colorkey_mode;
-};
-
-struct armada_plane {
- struct drm_plane base;
- spinlock_t lock;
- struct drm_framebuffer *old_fb;
- uint32_t src_hw;
- uint32_t dst_hw;
- uint32_t dst_yx;
- uint32_t ctrl0;
- struct {
- struct armada_vbl_event update;
- struct armada_regs regs[13];
- wait_queue_head_t wait;
- } vbl;
- struct armada_plane_properties prop;
-};
-#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
-
-
-static void
-armada_ovl_update_attr(struct armada_plane_properties *prop,
- struct armada_crtc *dcrtc)
-{
- writel_relaxed(prop->colorkey_yr, dcrtc->base + LCD_SPU_COLORKEY_Y);
- writel_relaxed(prop->colorkey_ug, dcrtc->base + LCD_SPU_COLORKEY_U);
- writel_relaxed(prop->colorkey_vb, dcrtc->base + LCD_SPU_COLORKEY_V);
-
- writel_relaxed(prop->brightness << 16 | prop->contrast,
- dcrtc->base + LCD_SPU_CONTRAST);
- /* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */
- writel_relaxed(prop->saturation << 16,
- dcrtc->base + LCD_SPU_SATURATION);
- writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE);
-
- spin_lock_irq(&dcrtc->irq_lock);
- armada_updatel(prop->colorkey_mode | CFG_ALPHAM_GRA,
- CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
- dcrtc->base + LCD_SPU_DMA_CTRL1);
-
- armada_updatel(ADV_GRACOLORKEY, 0, dcrtc->base + LCD_SPU_ADV_REG);
- spin_unlock_irq(&dcrtc->irq_lock);
-}
-
-/* === Plane support === */
-static void armada_plane_vbl(struct armada_crtc *dcrtc, void *data)
-{
- struct armada_plane *dplane = data;
- struct drm_framebuffer *fb;
-
- armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
-
- spin_lock(&dplane->lock);
- fb = dplane->old_fb;
- dplane->old_fb = NULL;
- spin_unlock(&dplane->lock);
-
- if (fb)
- armada_drm_queue_unref_work(dcrtc->crtc.dev, fb);
-}
-
-static unsigned armada_limit(int start, unsigned size, unsigned max)
-{
- int end = start + size;
- if (end < 0)
- return 0;
- if (start < 0)
- start = 0;
- return (unsigned)end > max ? max - start : end - start;
-}
-
-static int
-armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
- uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
-{
- struct armada_plane *dplane = drm_to_armada_plane(plane);
- struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- uint32_t val, ctrl0;
- unsigned idx = 0;
- int ret;
-
- crtc_w = armada_limit(crtc_x, crtc_w, dcrtc->crtc.mode.hdisplay);
- crtc_h = armada_limit(crtc_y, crtc_h, dcrtc->crtc.mode.vdisplay);
- ctrl0 = CFG_DMA_FMT(drm_fb_to_armada_fb(fb)->fmt) |
- CFG_DMA_MOD(drm_fb_to_armada_fb(fb)->mod) |
- CFG_CBSH_ENA | CFG_DMA_HSMOOTH | CFG_DMA_ENA;
-
- /* Does the position/size result in nothing to display? */
- if (crtc_w == 0 || crtc_h == 0) {
- ctrl0 &= ~CFG_DMA_ENA;
- }
-
- /*
- * FIXME: if the starting point is off screen, we need to
- * adjust src_x, src_y, src_w, src_h appropriately, and
- * according to the scale.
- */
-
- if (!dcrtc->plane) {
- dcrtc->plane = plane;
- armada_ovl_update_attr(&dplane->prop, dcrtc);
- }
-
- /* FIXME: overlay on an interlaced display */
- /* Just updating the position/size? */
- if (plane->fb == fb && dplane->ctrl0 == ctrl0) {
- val = (src_h & 0xffff0000) | src_w >> 16;
- dplane->src_hw = val;
- writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN);
- val = crtc_h << 16 | crtc_w;
- dplane->dst_hw = val;
- writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN);
- val = crtc_y << 16 | crtc_x;
- dplane->dst_yx = val;
- writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN);
- return 0;
- } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) {
- /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */
- armada_updatel(0, CFG_PDWN16x66 | CFG_PDWN32x66,
- dcrtc->base + LCD_SPU_SRAM_PARA1);
- }
-
- ret = wait_event_timeout(dplane->vbl.wait,
- list_empty(&dplane->vbl.update.node),
- HZ/25);
- if (ret < 0)
- return ret;
-
- if (plane->fb != fb) {
- struct armada_gem_object *obj = drm_fb_obj(fb);
- uint32_t sy, su, sv;
-
- /*
- * Take a reference on the new framebuffer - we want to
- * hold on to it while the hardware is displaying it.
- */
- drm_framebuffer_reference(fb);
-
- if (plane->fb) {
- struct drm_framebuffer *older_fb;
-
- spin_lock_irq(&dplane->lock);
- older_fb = dplane->old_fb;
- dplane->old_fb = plane->fb;
- spin_unlock_irq(&dplane->lock);
- if (older_fb)
- armada_drm_queue_unref_work(dcrtc->crtc.dev,
- older_fb);
- }
-
- src_y >>= 16;
- src_x >>= 16;
- sy = obj->dev_addr + fb->offsets[0] + src_y * fb->pitches[0] +
- src_x * fb->bits_per_pixel / 8;
- su = obj->dev_addr + fb->offsets[1] + src_y * fb->pitches[1] +
- src_x;
- sv = obj->dev_addr + fb->offsets[2] + src_y * fb->pitches[2] +
- src_x;
-
- armada_reg_queue_set(dplane->vbl.regs, idx, sy,
- LCD_SPU_DMA_START_ADDR_Y0);
- armada_reg_queue_set(dplane->vbl.regs, idx, su,
- LCD_SPU_DMA_START_ADDR_U0);
- armada_reg_queue_set(dplane->vbl.regs, idx, sv,
- LCD_SPU_DMA_START_ADDR_V0);
- armada_reg_queue_set(dplane->vbl.regs, idx, sy,
- LCD_SPU_DMA_START_ADDR_Y1);
- armada_reg_queue_set(dplane->vbl.regs, idx, su,
- LCD_SPU_DMA_START_ADDR_U1);
- armada_reg_queue_set(dplane->vbl.regs, idx, sv,
- LCD_SPU_DMA_START_ADDR_V1);
-
- val = fb->pitches[0] << 16 | fb->pitches[0];
- armada_reg_queue_set(dplane->vbl.regs, idx, val,
- LCD_SPU_DMA_PITCH_YC);
- val = fb->pitches[1] << 16 | fb->pitches[2];
- armada_reg_queue_set(dplane->vbl.regs, idx, val,
- LCD_SPU_DMA_PITCH_UV);
- }
-
- val = (src_h & 0xffff0000) | src_w >> 16;
- if (dplane->src_hw != val) {
- dplane->src_hw = val;
- armada_reg_queue_set(dplane->vbl.regs, idx, val,
- LCD_SPU_DMA_HPXL_VLN);
- }
- val = crtc_h << 16 | crtc_w;
- if (dplane->dst_hw != val) {
- dplane->dst_hw = val;
- armada_reg_queue_set(dplane->vbl.regs, idx, val,
- LCD_SPU_DZM_HPXL_VLN);
- }
- val = crtc_y << 16 | crtc_x;
- if (dplane->dst_yx != val) {
- dplane->dst_yx = val;
- armada_reg_queue_set(dplane->vbl.regs, idx, val,
- LCD_SPU_DMA_OVSA_HPXL_VLN);
- }
- if (dplane->ctrl0 != ctrl0) {
- dplane->ctrl0 = ctrl0;
- armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0,
- CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_FTOGGLE |
- CFG_DMA_HSMOOTH | CFG_DMA_TSTMODE |
- CFG_DMA_MOD(CFG_SWAPRB | CFG_SWAPUV | CFG_SWAPYU |
- CFG_YUV2RGB) | CFG_DMA_ENA,
- LCD_SPU_DMA_CTRL0);
- }
- if (idx) {
- armada_reg_queue_end(dplane->vbl.regs, idx);
- armada_drm_vbl_event_add(dcrtc, &dplane->vbl.update);
- }
- return 0;
-}
-
-static int armada_plane_disable(struct drm_plane *plane)
-{
- struct armada_plane *dplane = drm_to_armada_plane(plane);
- struct drm_framebuffer *fb;
- struct armada_crtc *dcrtc;
-
- if (!dplane->base.crtc)
- return 0;
-
- dcrtc = drm_to_armada_crtc(dplane->base.crtc);
- dcrtc->plane = NULL;
-
- spin_lock_irq(&dcrtc->irq_lock);
- armada_drm_vbl_event_remove(dcrtc, &dplane->vbl.update);
- armada_updatel(0, CFG_DMA_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
- dplane->ctrl0 = 0;
- spin_unlock_irq(&dcrtc->irq_lock);
-
- /* Power down the Y/U/V FIFOs */
- armada_updatel(CFG_PDWN16x66 | CFG_PDWN32x66, 0,
- dcrtc->base + LCD_SPU_SRAM_PARA1);
-
- if (plane->fb)
- drm_framebuffer_unreference(plane->fb);
-
- spin_lock_irq(&dplane->lock);
- fb = dplane->old_fb;
- dplane->old_fb = NULL;
- spin_unlock_irq(&dplane->lock);
- if (fb)
- drm_framebuffer_unreference(fb);
-
- return 0;
-}
-
-static void armada_plane_destroy(struct drm_plane *plane)
-{
- kfree(plane);
-}
-
-static int armada_plane_set_property(struct drm_plane *plane,
- struct drm_property *property, uint64_t val)
-{
- struct armada_private *priv = plane->dev->dev_private;
- struct armada_plane *dplane = drm_to_armada_plane(plane);
- bool update_attr = false;
-
- if (property == priv->colorkey_prop) {
-#define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)
- dplane->prop.colorkey_yr = CCC(K2R(val));
- dplane->prop.colorkey_ug = CCC(K2G(val));
- dplane->prop.colorkey_vb = CCC(K2B(val));
-#undef CCC
- update_attr = true;
- } else if (property == priv->colorkey_min_prop) {
- dplane->prop.colorkey_yr &= ~0x00ff0000;
- dplane->prop.colorkey_yr |= K2R(val) << 16;
- dplane->prop.colorkey_ug &= ~0x00ff0000;
- dplane->prop.colorkey_ug |= K2G(val) << 16;
- dplane->prop.colorkey_vb &= ~0x00ff0000;
- dplane->prop.colorkey_vb |= K2B(val) << 16;
- update_attr = true;
- } else if (property == priv->colorkey_max_prop) {
- dplane->prop.colorkey_yr &= ~0xff000000;
- dplane->prop.colorkey_yr |= K2R(val) << 24;
- dplane->prop.colorkey_ug &= ~0xff000000;
- dplane->prop.colorkey_ug |= K2G(val) << 24;
- dplane->prop.colorkey_vb &= ~0xff000000;
- dplane->prop.colorkey_vb |= K2B(val) << 24;
- update_attr = true;
- } else if (property == priv->colorkey_val_prop) {
- dplane->prop.colorkey_yr &= ~0x0000ff00;
- dplane->prop.colorkey_yr |= K2R(val) << 8;
- dplane->prop.colorkey_ug &= ~0x0000ff00;
- dplane->prop.colorkey_ug |= K2G(val) << 8;
- dplane->prop.colorkey_vb &= ~0x0000ff00;
- dplane->prop.colorkey_vb |= K2B(val) << 8;
- update_attr = true;
- } else if (property == priv->colorkey_alpha_prop) {
- dplane->prop.colorkey_yr &= ~0x000000ff;
- dplane->prop.colorkey_yr |= K2R(val);
- dplane->prop.colorkey_ug &= ~0x000000ff;
- dplane->prop.colorkey_ug |= K2G(val);
- dplane->prop.colorkey_vb &= ~0x000000ff;
- dplane->prop.colorkey_vb |= K2B(val);
- update_attr = true;
- } else if (property == priv->colorkey_mode_prop) {
- dplane->prop.colorkey_mode &= ~CFG_CKMODE_MASK;
- dplane->prop.colorkey_mode |= CFG_CKMODE(val);
- update_attr = true;
- } else if (property == priv->brightness_prop) {
- dplane->prop.brightness = val - 256;
- update_attr = true;
- } else if (property == priv->contrast_prop) {
- dplane->prop.contrast = val;
- update_attr = true;
- } else if (property == priv->saturation_prop) {
- dplane->prop.saturation = val;
- update_attr = true;
- }
-
- if (update_attr && dplane->base.crtc)
- armada_ovl_update_attr(&dplane->prop,
- drm_to_armada_crtc(dplane->base.crtc));
-
- return 0;
-}
-
-static const struct drm_plane_funcs armada_plane_funcs = {
- .update_plane = armada_plane_update,
- .disable_plane = armada_plane_disable,
- .destroy = armada_plane_destroy,
- .set_property = armada_plane_set_property,
-};
-
-static const uint32_t armada_formats[] = {
- DRM_FORMAT_UYVY,
- DRM_FORMAT_YUYV,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YVU420,
- DRM_FORMAT_YUV422,
- DRM_FORMAT_YVU422,
- DRM_FORMAT_VYUY,
- DRM_FORMAT_YVYU,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_ABGR1555,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR565,
-};
-
-static struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
- { CKMODE_DISABLE, "disabled" },
- { CKMODE_Y, "Y component" },
- { CKMODE_U, "U component" },
- { CKMODE_V, "V component" },
- { CKMODE_RGB, "RGB" },
- { CKMODE_R, "R component" },
- { CKMODE_G, "G component" },
- { CKMODE_B, "B component" },
-};
-
-static int armada_overlay_create_properties(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
-
- if (priv->colorkey_prop)
- return 0;
-
- priv->colorkey_prop = drm_property_create_range(dev, 0,
- "colorkey", 0, 0xffffff);
- priv->colorkey_min_prop = drm_property_create_range(dev, 0,
- "colorkey_min", 0, 0xffffff);
- priv->colorkey_max_prop = drm_property_create_range(dev, 0,
- "colorkey_max", 0, 0xffffff);
- priv->colorkey_val_prop = drm_property_create_range(dev, 0,
- "colorkey_val", 0, 0xffffff);
- priv->colorkey_alpha_prop = drm_property_create_range(dev, 0,
- "colorkey_alpha", 0, 0xffffff);
- priv->colorkey_mode_prop = drm_property_create_enum(dev, 0,
- "colorkey_mode",
- armada_drm_colorkey_enum_list,
- ARRAY_SIZE(armada_drm_colorkey_enum_list));
- priv->brightness_prop = drm_property_create_range(dev, 0,
- "brightness", 0, 256 + 255);
- priv->contrast_prop = drm_property_create_range(dev, 0,
- "contrast", 0, 0x7fff);
- priv->saturation_prop = drm_property_create_range(dev, 0,
- "saturation", 0, 0x7fff);
-
- if (!priv->colorkey_prop)
- return -ENOMEM;
-
- return 0;
-}
-
-int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
-{
- struct armada_private *priv = dev->dev_private;
- struct drm_mode_object *mobj;
- struct armada_plane *dplane;
- int ret;
-
- ret = armada_overlay_create_properties(dev);
- if (ret)
- return ret;
-
- dplane = kzalloc(sizeof(*dplane), GFP_KERNEL);
- if (!dplane)
- return -ENOMEM;
-
- spin_lock_init(&dplane->lock);
- init_waitqueue_head(&dplane->vbl.wait);
- armada_drm_vbl_event_init(&dplane->vbl.update, armada_plane_vbl,
- dplane);
-
- drm_plane_init(dev, &dplane->base, crtcs, &armada_plane_funcs,
- armada_formats, ARRAY_SIZE(armada_formats), false);
-
- dplane->prop.colorkey_yr = 0xfefefe00;
- dplane->prop.colorkey_ug = 0x01010100;
- dplane->prop.colorkey_vb = 0x01010100;
- dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB);
- dplane->prop.brightness = 0;
- dplane->prop.contrast = 0x4000;
- dplane->prop.saturation = 0x4000;
-
- mobj = &dplane->base.base;
- drm_object_attach_property(mobj, priv->colorkey_prop,
- 0x0101fe);
- drm_object_attach_property(mobj, priv->colorkey_min_prop,
- 0x0101fe);
- drm_object_attach_property(mobj, priv->colorkey_max_prop,
- 0x0101fe);
- drm_object_attach_property(mobj, priv->colorkey_val_prop,
- 0x0101fe);
- drm_object_attach_property(mobj, priv->colorkey_alpha_prop,
- 0x000000);
- drm_object_attach_property(mobj, priv->colorkey_mode_prop,
- CKMODE_RGB);
- drm_object_attach_property(mobj, priv->brightness_prop, 256);
- drm_object_attach_property(mobj, priv->contrast_prop,
- dplane->prop.contrast);
- drm_object_attach_property(mobj, priv->saturation_prop,
- dplane->prop.saturation);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/armada/armada_slave.c b/drivers/gpu/drm/armada/armada_slave.c
deleted file mode 100644
index 00d0fac..0000000
--- a/drivers/gpu/drm/armada/armada_slave.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- * Rewritten from the dovefb driver, and Armada510 manuals.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
-#include "armada_drm.h"
-#include "armada_output.h"
-#include "armada_slave.h"
-
-static int armada_drm_slave_get_modes(struct drm_connector *conn)
-{
- struct drm_encoder *enc = armada_drm_connector_encoder(conn);
- int count = 0;
-
- if (enc) {
- struct drm_encoder_slave *slave = to_encoder_slave(enc);
-
- count = slave->slave_funcs->get_modes(enc, conn);
- }
-
- return count;
-}
-
-static void armada_drm_slave_destroy(struct drm_encoder *enc)
-{
- struct drm_encoder_slave *slave = to_encoder_slave(enc);
- struct i2c_client *client = drm_i2c_encoder_get_client(enc);
-
- if (slave->slave_funcs)
- slave->slave_funcs->destroy(enc);
- if (client)
- i2c_put_adapter(client->adapter);
-
- drm_encoder_cleanup(&slave->base);
- kfree(slave);
-}
-
-static const struct drm_encoder_funcs armada_drm_slave_encoder_funcs = {
- .destroy = armada_drm_slave_destroy,
-};
-
-static const struct drm_connector_helper_funcs armada_drm_slave_helper_funcs = {
- .get_modes = armada_drm_slave_get_modes,
- .mode_valid = armada_drm_slave_encoder_mode_valid,
- .best_encoder = armada_drm_connector_encoder,
-};
-
-static const struct drm_encoder_helper_funcs drm_slave_encoder_helpers = {
- .dpms = drm_i2c_encoder_dpms,
- .save = drm_i2c_encoder_save,
- .restore = drm_i2c_encoder_restore,
- .mode_fixup = drm_i2c_encoder_mode_fixup,
- .prepare = drm_i2c_encoder_prepare,
- .commit = drm_i2c_encoder_commit,
- .mode_set = drm_i2c_encoder_mode_set,
- .detect = drm_i2c_encoder_detect,
-};
-
-static int
-armada_drm_conn_slave_create(struct drm_connector *conn, const void *data)
-{
- const struct armada_drm_slave_config *config = data;
- struct drm_encoder_slave *slave;
- struct i2c_adapter *adap;
- int ret;
-
- conn->interlace_allowed = config->interlace_allowed;
- conn->doublescan_allowed = config->doublescan_allowed;
- conn->polled = config->polled;
-
- drm_connector_helper_add(conn, &armada_drm_slave_helper_funcs);
-
- slave = kzalloc(sizeof(*slave), GFP_KERNEL);
- if (!slave)
- return -ENOMEM;
-
- slave->base.possible_crtcs = config->crtcs;
-
- adap = i2c_get_adapter(config->i2c_adapter_id);
- if (!adap) {
- kfree(slave);
- return -EPROBE_DEFER;
- }
-
- ret = drm_encoder_init(conn->dev, &slave->base,
- &armada_drm_slave_encoder_funcs,
- DRM_MODE_ENCODER_TMDS);
- if (ret) {
- DRM_ERROR("unable to init encoder\n");
- i2c_put_adapter(adap);
- kfree(slave);
- return ret;
- }
-
- ret = drm_i2c_encoder_init(conn->dev, slave, adap, &config->info);
- i2c_put_adapter(adap);
- if (ret) {
- DRM_ERROR("unable to init encoder slave\n");
- armada_drm_slave_destroy(&slave->base);
- return ret;
- }
-
- drm_encoder_helper_add(&slave->base, &drm_slave_encoder_helpers);
-
- ret = slave->slave_funcs->create_resources(&slave->base, conn);
- if (ret) {
- armada_drm_slave_destroy(&slave->base);
- return ret;
- }
-
- ret = drm_mode_connector_attach_encoder(conn, &slave->base);
- if (ret) {
- armada_drm_slave_destroy(&slave->base);
- return ret;
- }
-
- conn->encoder = &slave->base;
-
- return ret;
-}
-
-static const struct armada_output_type armada_drm_conn_slave = {
- .connector_type = DRM_MODE_CONNECTOR_HDMIA,
- .create = armada_drm_conn_slave_create,
- .set_property = armada_drm_slave_encoder_set_property,
-};
-
-int armada_drm_connector_slave_create(struct drm_device *dev,
- const struct armada_drm_slave_config *config)
-{
- return armada_output_create(dev, &armada_drm_conn_slave, config);
-}
diff --git a/drivers/gpu/drm/armada/armada_slave.h b/drivers/gpu/drm/armada/armada_slave.h
deleted file mode 100644
index bf2374c..0000000
--- a/drivers/gpu/drm/armada/armada_slave.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_SLAVE_H
-#define ARMADA_SLAVE_H
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-
-struct armada_drm_slave_config {
- int i2c_adapter_id;
- uint32_t crtcs;
- uint8_t polled;
- bool interlace_allowed;
- bool doublescan_allowed;
- struct i2c_board_info info;
-};
-
-int armada_drm_connector_slave_create(struct drm_device *dev,
- const struct armada_drm_slave_config *);
-
-#endif
diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig
index 8a784c4..da4a51e 100644
--- a/drivers/gpu/drm/ast/Kconfig
+++ b/drivers/gpu/drm/ast/Kconfig
@@ -6,7 +6,6 @@ config DRM_AST
select FB_SYS_FILLRECT
select FB_SYS_IMAGEBLIT
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_TTM
help
Say yes for experimental AST GPU driver. Do not enable
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 5137f15..32e270d 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -211,6 +211,7 @@ static struct drm_driver driver = {
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
+ .gem_init_object = ast_gem_init_object,
.gem_free_object = ast_gem_free_object,
.dumb_create = ast_dumb_create,
.dumb_map_offset = ast_dumb_mmap_offset,
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 9833a1b..8492b68 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -323,6 +323,7 @@ extern int ast_dumb_create(struct drm_file *file,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
+extern int ast_gem_init_object(struct drm_gem_object *obj);
extern void ast_gem_free_object(struct drm_gem_object *obj);
extern int ast_dumb_mmap_offset(struct drm_file *file,
struct drm_device *dev,
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index af0b868..7f6152d 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -449,6 +449,12 @@ int ast_dumb_create(struct drm_file *file,
return 0;
}
+int ast_gem_init_object(struct drm_gem_object *obj)
+{
+ BUG();
+ return 0;
+}
+
void ast_bo_unref(struct ast_bo **bo)
{
struct ttm_buffer_object *tbo;
diff --git a/drivers/gpu/drm/cirrus/Kconfig b/drivers/gpu/drm/cirrus/Kconfig
index 9864559..bf67b22 100644
--- a/drivers/gpu/drm/cirrus/Kconfig
+++ b/drivers/gpu/drm/cirrus/Kconfig
@@ -5,7 +5,6 @@ config DRM_CIRRUS_QEMU
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_TTM
help
This is a KMS driver for emulated cirrus device in qemu.
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 953fc8a..138364d 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -97,6 +97,7 @@ static struct drm_driver driver = {
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
+ .gem_init_object = cirrus_gem_init_object,
.gem_free_object = cirrus_gem_free_object,
.dumb_create = cirrus_dumb_create,
.dumb_map_offset = cirrus_dumb_mmap_offset,
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index b6aded7..9b0bb91 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -191,6 +191,7 @@ int cirrus_device_init(struct cirrus_device *cdev,
struct pci_dev *pdev,
uint32_t flags);
void cirrus_device_fini(struct cirrus_device *cdev);
+int cirrus_gem_init_object(struct drm_gem_object *obj);
void cirrus_gem_free_object(struct drm_gem_object *obj);
int cirrus_dumb_mmap_offset(struct drm_file *file,
struct drm_device *dev,
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 78e76f2..f130a53 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -255,6 +255,12 @@ int cirrus_dumb_create(struct drm_file *file,
return 0;
}
+int cirrus_gem_init_object(struct drm_gem_object *obj)
+{
+ BUG();
+ return 0;
+}
+
void cirrus_bo_unref(struct cirrus_bo **bo)
{
struct ttm_buffer_object *tbo;
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index adabc3d..60685b2 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -494,12 +494,13 @@ static struct drm_encoder *cirrus_encoder_init(struct drm_device *dev)
int cirrus_vga_get_modes(struct drm_connector *connector)
{
- int count;
-
/* Just add a static list of modes */
- count = drm_add_modes_noedid(connector, 1280, 1024);
- drm_set_preferred_mode(connector, 1024, 768);
- return count;
+ drm_add_modes_noedid(connector, 640, 480);
+ drm_add_modes_noedid(connector, 800, 600);
+ drm_add_modes_noedid(connector, 1024, 768);
+ drm_add_modes_noedid(connector, 1280, 1024);
+
+ return 4;
}
static int cirrus_vga_mode_valid(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index a4b017b..224ff96 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -334,6 +334,7 @@ int drm_addctx(struct drm_device *dev, void *data,
mutex_lock(&dev->ctxlist_mutex);
list_add(&ctx_entry->head, &dev->ctxlist);
+ ++dev->ctx_count;
mutex_unlock(&dev->ctxlist_mutex);
return 0;
@@ -431,6 +432,7 @@ int drm_rmctx(struct drm_device *dev, void *data,
if (pos->handle == ctx->handle) {
list_del(&pos->head);
kfree(pos);
+ --dev->ctx_count;
}
}
}
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d6cf77c..bff2fa9 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -202,7 +202,6 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
{ DRM_MODE_CONNECTOR_TV, "TV" },
{ DRM_MODE_CONNECTOR_eDP, "eDP" },
{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
- { DRM_MODE_CONNECTOR_DSI, "DSI" },
};
static const struct drm_prop_enum_list drm_encoder_enum_list[] =
@@ -212,7 +211,6 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] =
{ DRM_MODE_ENCODER_LVDS, "LVDS" },
{ DRM_MODE_ENCODER_TVDAC, "TV" },
{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
- { DRM_MODE_ENCODER_DSI, "DSI" },
};
void drm_connector_ida_init(void)
@@ -1303,7 +1301,7 @@ static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
}
/**
- * drm_crtc_convert_umode - convert a modeinfo into a drm_display_mode
+ * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
* @out: drm_display_mode to return to the user
* @in: drm_mode_modeinfo to use
*
@@ -1319,9 +1317,6 @@ static int drm_crtc_convert_umode(struct drm_display_mode *out,
if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
return -ERANGE;
- if ((in->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX)
- return -EINVAL;
-
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
@@ -1557,7 +1552,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
crtc = obj_to_crtc(obj);
@@ -1584,19 +1579,6 @@ out:
return ret;
}
-static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
- const struct drm_file *file_priv)
-{
- /*
- * If user-space hasn't configured the driver to expose the stereo 3D
- * modes, don't expose them.
- */
- if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode))
- return false;
-
- return true;
-}
-
/**
* drm_mode_getconnector - get connector configuration
* @dev: drm device for the ioctl
@@ -1641,7 +1623,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, out_resp->connector_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
connector = obj_to_connector(obj);
@@ -1662,8 +1644,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
/* delayed so we get modes regardless of pre-fill_modes state */
list_for_each_entry(mode, &connector->modes, head)
- if (drm_mode_expose_to_userspace(mode, file_priv))
- mode_count++;
+ mode_count++;
out_resp->connector_id = connector->base.id;
out_resp->connector_type = connector->connector_type;
@@ -1685,9 +1666,6 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
copied = 0;
mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
list_for_each_entry(mode, &connector->modes, head) {
- if (!drm_mode_expose_to_userspace(mode, file_priv))
- continue;
-
drm_crtc_convert_to_umode(&u_mode, mode);
if (copy_to_user(mode_ptr + copied,
&u_mode, sizeof(u_mode))) {
@@ -1757,7 +1735,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, enc_resp->encoder_id,
DRM_MODE_OBJECT_ENCODER);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
encoder = obj_to_encoder(obj);
@@ -2062,45 +2040,6 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
}
EXPORT_SYMBOL(drm_mode_set_config_internal);
-/*
- * Checks that the framebuffer is big enough for the CRTC viewport
- * (x, y, hdisplay, vdisplay)
- */
-static int drm_crtc_check_viewport(const struct drm_crtc *crtc,
- int x, int y,
- const struct drm_display_mode *mode,
- const struct drm_framebuffer *fb)
-
-{
- int hdisplay, vdisplay;
-
- hdisplay = mode->hdisplay;
- vdisplay = mode->vdisplay;
-
- if (drm_mode_is_stereo(mode)) {
- struct drm_display_mode adjusted = *mode;
-
- drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE);
- hdisplay = adjusted.crtc_hdisplay;
- vdisplay = adjusted.crtc_vdisplay;
- }
-
- if (crtc->invert_dimensions)
- swap(hdisplay, vdisplay);
-
- if (hdisplay > fb->width ||
- vdisplay > fb->height ||
- x > fb->width - hdisplay ||
- y > fb->height - vdisplay) {
- DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
- fb->width, fb->height, hdisplay, vdisplay, x, y,
- crtc->invert_dimensions ? " (inverted)" : "");
- return -ENOSPC;
- }
-
- return 0;
-}
-
/**
* drm_mode_setcrtc - set CRTC configuration
* @dev: drm device for the ioctl
@@ -2141,13 +2080,14 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
crtc = obj_to_crtc(obj);
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
if (crtc_req->mode_valid) {
+ int hdisplay, vdisplay;
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
@@ -2164,7 +2104,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (!fb) {
DRM_DEBUG_KMS("Unknown FB ID%d\n",
crtc_req->fb_id);
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
}
@@ -2183,11 +2123,23 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
- ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
- mode, fb);
- if (ret)
+ hdisplay = mode->hdisplay;
+ vdisplay = mode->vdisplay;
+
+ if (crtc->invert_dimensions)
+ swap(hdisplay, vdisplay);
+
+ if (hdisplay > fb->width ||
+ vdisplay > fb->height ||
+ crtc_req->x > fb->width - hdisplay ||
+ crtc_req->y > fb->height - vdisplay) {
+ DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
+ fb->width, fb->height,
+ hdisplay, vdisplay, crtc_req->x, crtc_req->y,
+ crtc->invert_dimensions ? " (inverted)" : "");
+ ret = -ENOSPC;
goto out;
-
+ }
}
if (crtc_req->count_connectors == 0 && mode) {
@@ -2232,7 +2184,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (!obj) {
DRM_DEBUG_KMS("Connector id %d unknown\n",
out_id);
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
connector = obj_to_connector(obj);
@@ -2280,7 +2232,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
- return -ENOENT;
+ return -EINVAL;
}
crtc = obj_to_crtc(obj);
@@ -2489,8 +2441,6 @@ static int format_check(const struct drm_mode_fb_cmd2 *r)
case DRM_FORMAT_YVU444:
return 0;
default:
- DRM_DEBUG_KMS("invalid pixel format %s\n",
- drm_get_format_name(r->pixel_format));
return -EINVAL;
}
}
@@ -2656,7 +2606,7 @@ fail_lookup:
mutex_unlock(&dev->mode_config.fb_lock);
mutex_unlock(&file_priv->fbs_lock);
- return -ENOENT;
+ return -EINVAL;
}
/**
@@ -2684,7 +2634,7 @@ int drm_mode_getfb(struct drm_device *dev,
fb = drm_framebuffer_lookup(dev, r->fb_id);
if (!fb)
- return -ENOENT;
+ return -EINVAL;
r->height = fb->height;
r->width = fb->width;
@@ -2729,7 +2679,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
fb = drm_framebuffer_lookup(dev, r->fb_id);
if (!fb)
- return -ENOENT;
+ return -EINVAL;
num_clips = r->num_clips;
clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
@@ -3061,7 +3011,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
drm_modeset_lock_all(dev);
obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto done;
}
property = obj_to_property(obj);
@@ -3190,7 +3140,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
drm_modeset_lock_all(dev);
obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto done;
}
blob = obj_to_blob(obj);
@@ -3351,7 +3301,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
if (!obj->properties) {
@@ -3404,10 +3354,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
- if (!arg_obj) {
- ret = -ENOENT;
+ if (!arg_obj)
goto out;
- }
if (!arg_obj->properties)
goto out;
@@ -3420,10 +3368,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
prop_obj = drm_mode_object_find(dev, arg->prop_id,
DRM_MODE_OBJECT_PROPERTY);
- if (!prop_obj) {
- ret = -ENOENT;
+ if (!prop_obj)
goto out;
- }
property = obj_to_property(prop_obj);
if (!drm_property_change_is_valid(property, arg->value))
@@ -3508,7 +3454,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
drm_modeset_lock_all(dev);
obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
crtc = obj_to_crtc(obj);
@@ -3567,7 +3513,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
drm_modeset_lock_all(dev);
obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
crtc = obj_to_crtc(obj);
@@ -3610,6 +3556,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
struct drm_framebuffer *fb = NULL, *old_fb = NULL;
struct drm_pending_vblank_event *e = NULL;
unsigned long flags;
+ int hdisplay, vdisplay;
int ret = -EINVAL;
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
@@ -3621,7 +3568,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj)
- return -ENOENT;
+ return -EINVAL;
crtc = obj_to_crtc(obj);
mutex_lock(&crtc->mutex);
@@ -3638,14 +3585,25 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
- if (!fb) {
- ret = -ENOENT;
+ if (!fb)
goto out;
- }
- ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb);
- if (ret)
+ hdisplay = crtc->mode.hdisplay;
+ vdisplay = crtc->mode.vdisplay;
+
+ if (crtc->invert_dimensions)
+ swap(hdisplay, vdisplay);
+
+ if (hdisplay > fb->width ||
+ vdisplay > fb->height ||
+ crtc->x > fb->width - hdisplay ||
+ crtc->y > fb->height - vdisplay) {
+ DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
+ fb->width, fb->height, hdisplay, vdisplay, crtc->x, crtc->y,
+ crtc->invert_dimensions ? " (inverted)" : "");
+ ret = -ENOSPC;
goto out;
+ }
if (crtc->fb->pixel_format != fb->pixel_format) {
DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
@@ -3830,8 +3788,7 @@ void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
*bpp = 32;
break;
default:
- DRM_DEBUG_KMS("unsupported pixel format %s\n",
- drm_get_format_name(format));
+ DRM_DEBUG_KMS("unsupported pixel format\n");
*depth = 0;
*bpp = 0;
break;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 01361ab..c722c3b 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -39,10 +39,6 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_edid.h>
-MODULE_AUTHOR("David Airlie, Jesse Barnes");
-MODULE_DESCRIPTION("DRM KMS helper");
-MODULE_LICENSE("GPL and additional rights");
-
/**
* drm_helper_move_panel_connectors_to_head() - move panels to the front in the
* connector list
@@ -80,8 +76,7 @@ static void drm_mode_validate_flag(struct drm_connector *connector,
{
struct drm_display_mode *mode;
- if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
- DRM_MODE_FLAG_3D_MASK))
+ if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
return;
list_for_each_entry(mode, &connector->modes, head) {
@@ -91,9 +86,6 @@ static void drm_mode_validate_flag(struct drm_connector *connector,
if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
!(flags & DRM_MODE_FLAG_DBLSCAN))
mode->status = MODE_NO_DBLESCAN;
- if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
- !(flags & DRM_MODE_FLAG_3D_MASK))
- mode->status = MODE_NO_STEREO;
}
return;
@@ -113,9 +105,9 @@ static void drm_mode_validate_flag(struct drm_connector *connector,
* then culled (based on validity and the @maxX, @maxY parameters) and put into
* the normal modes list.
*
- * Intended to be use as a generic implementation of the ->fill_modes()
- * @connector vfunc for drivers that use the crtc helpers for output mode
- * filtering and detection.
+ * Intended to be use as a generic implementation of the ->probe() @connector
+ * callback for drivers that use the crtc helpers for output mode filtering and
+ * detection.
*
* RETURNS:
* Number of modes found on @connector.
@@ -183,8 +175,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
mode_flags |= DRM_MODE_FLAG_INTERLACE;
if (connector->doublescan_allowed)
mode_flags |= DRM_MODE_FLAG_DBLSCAN;
- if (connector->stereo_allowed)
- mode_flags |= DRM_MODE_FLAG_3D_MASK;
drm_mode_validate_flag(connector, mode_flags);
list_for_each_entry(mode, &connector->modes, head) {
@@ -405,25 +395,22 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
- struct drm_display_mode *adjusted_mode, saved_mode;
+ struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
struct drm_encoder_helper_funcs *encoder_funcs;
int saved_x, saved_y;
- bool saved_enabled;
struct drm_encoder *encoder;
bool ret = true;
- saved_enabled = crtc->enabled;
crtc->enabled = drm_helper_crtc_in_use(crtc);
if (!crtc->enabled)
return true;
adjusted_mode = drm_mode_duplicate(dev, mode);
- if (!adjusted_mode) {
- crtc->enabled = saved_enabled;
+ if (!adjusted_mode)
return false;
- }
+ saved_hwmode = crtc->hwmode;
saved_mode = crtc->mode;
saved_x = crtc->x;
saved_y = crtc->y;
@@ -542,7 +529,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
done:
drm_mode_destroy(dev, adjusted_mode);
if (!ret) {
- crtc->enabled = saved_enabled;
+ crtc->hwmode = saved_hwmode;
crtc->mode = saved_mode;
crtc->x = saved_x;
crtc->y = saved_y;
@@ -570,14 +557,6 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
continue;
connector->encoder = NULL;
-
- /*
- * drm_helper_disable_unused_functions() ought to be
- * doing this, but since we've decoupled the encoder
- * from the connector above, the required connection
- * between them is henceforth no longer available.
- */
- connector->dpms = DRM_MODE_DPMS_OFF;
}
}
@@ -604,8 +583,9 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
int drm_crtc_helper_set_config(struct drm_mode_set *set)
{
struct drm_device *dev;
- struct drm_crtc *new_crtc;
+ struct drm_crtc *save_crtcs, *new_crtc, *crtc;
struct drm_encoder *save_encoders, *new_encoder, *encoder;
+ struct drm_framebuffer *old_fb = NULL;
bool mode_changed = false; /* if true do a full mode set */
bool fb_changed = false; /* if true and !mode_changed just do a flip */
struct drm_connector *save_connectors, *connector;
@@ -641,28 +621,38 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
dev = set->crtc->dev;
- /*
- * Allocate space for the backup of all (non-pointer) encoder and
- * connector data.
- */
+ /* Allocate space for the backup of all (non-pointer) crtc, encoder and
+ * connector data. */
+ save_crtcs = kzalloc(dev->mode_config.num_crtc *
+ sizeof(struct drm_crtc), GFP_KERNEL);
+ if (!save_crtcs)
+ return -ENOMEM;
+
save_encoders = kzalloc(dev->mode_config.num_encoder *
sizeof(struct drm_encoder), GFP_KERNEL);
- if (!save_encoders)
+ if (!save_encoders) {
+ kfree(save_crtcs);
return -ENOMEM;
+ }
save_connectors = kzalloc(dev->mode_config.num_connector *
sizeof(struct drm_connector), GFP_KERNEL);
if (!save_connectors) {
+ kfree(save_crtcs);
kfree(save_encoders);
return -ENOMEM;
}
- /*
- * Copy data. Note that driver private data is not affected.
+ /* Copy data. Note that driver private data is not affected.
* Should anything bad happen only the expected state is
* restored, not the drivers personal bookkeeping.
*/
count = 0;
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ save_crtcs[count++] = *crtc;
+ }
+
+ count = 0;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
save_encoders[count++] = *encoder;
}
@@ -785,17 +775,19 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
mode_changed = true;
if (mode_changed) {
- if (drm_helper_crtc_in_use(set->crtc)) {
+ set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
+ if (set->crtc->enabled) {
DRM_DEBUG_KMS("attempting to set mode from"
" userspace\n");
drm_mode_debug_printmodeline(set->mode);
+ old_fb = set->crtc->fb;
set->crtc->fb = set->fb;
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
set->x, set->y,
- save_set.fb)) {
+ old_fb)) {
DRM_ERROR("failed to set mode on [CRTC:%d]\n",
set->crtc->base.id);
- set->crtc->fb = save_set.fb;
+ set->crtc->fb = old_fb;
ret = -EINVAL;
goto fail;
}
@@ -810,24 +802,31 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
} else if (fb_changed) {
set->crtc->x = set->x;
set->crtc->y = set->y;
- set->crtc->fb = set->fb;
+
+ old_fb = set->crtc->fb;
+ if (set->crtc->fb != set->fb)
+ set->crtc->fb = set->fb;
ret = crtc_funcs->mode_set_base(set->crtc,
- set->x, set->y, save_set.fb);
+ set->x, set->y, old_fb);
if (ret != 0) {
- set->crtc->x = save_set.x;
- set->crtc->y = save_set.y;
- set->crtc->fb = save_set.fb;
+ set->crtc->fb = old_fb;
goto fail;
}
}
kfree(save_connectors);
kfree(save_encoders);
+ kfree(save_crtcs);
return 0;
fail:
/* Restore all previous data. */
count = 0;
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ *crtc = save_crtcs[count++];
+ }
+
+ count = 0;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
*encoder = save_encoders[count++];
}
@@ -845,6 +844,7 @@ fail:
kfree(save_connectors);
kfree(save_encoders);
+ kfree(save_crtcs);
return ret;
}
EXPORT_SYMBOL(drm_crtc_helper_set_config);
@@ -1125,14 +1125,14 @@ void drm_kms_helper_poll_fini(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
-bool drm_helper_hpd_irq_event(struct drm_device *dev)
+void drm_helper_hpd_irq_event(struct drm_device *dev)
{
struct drm_connector *connector;
enum drm_connector_status old_status;
bool changed = false;
if (!dev->mode_config.poll_enabled)
- return false;
+ return;
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -1157,7 +1157,5 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
if (changed)
drm_kms_helper_hotplug_event(dev);
-
- return changed;
}
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b4b51d4..a05087c 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -42,7 +42,7 @@
* Initialization, etc.
**************************************************/
-static const struct drm_info_list drm_debugfs_list[] = {
+static struct drm_info_list drm_debugfs_list[] = {
{"name", drm_name_info, 0},
{"vm", drm_vm_info, 0},
{"clients", drm_clients_info, 0},
@@ -84,7 +84,7 @@ static const struct file_operations drm_debugfs_fops = {
* Create a given set of debugfs files represented by an array of
* gdm_debugfs_lists in the given root directory.
*/
-int drm_debugfs_create_files(const struct drm_info_list *files, int count,
+int drm_debugfs_create_files(struct drm_info_list *files, int count,
struct dentry *root, struct drm_minor *minor)
{
struct drm_device *dev = minor->dev;
@@ -188,7 +188,7 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
*
* Remove all debugfs entries created by debugfs_init().
*/
-int drm_debugfs_remove_files(const struct drm_info_list *files, int count,
+int drm_debugfs_remove_files(struct drm_info_list *files, int count,
struct drm_minor *minor)
{
struct list_head *pos, *q;
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 9e978aa..89e1966 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -228,12 +228,12 @@ i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
EXPORT_SYMBOL(i2c_dp_aux_add_bus);
/* Helpers for DP link training */
-static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
+static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
{
return link_status[r - DP_LANE0_1_STATUS];
}
-static u8 dp_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
+static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
int lane)
{
int i = DP_LANE0_1_STATUS + (lane >> 1);
@@ -242,7 +242,7 @@ static u8 dp_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
return (l >> s) & 0xf;
}
-bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
+bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count)
{
u8 lane_align;
@@ -262,7 +262,7 @@ bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
}
EXPORT_SYMBOL(drm_dp_channel_eq_ok);
-bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
+bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count)
{
int lane;
@@ -277,7 +277,7 @@ bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
}
EXPORT_SYMBOL(drm_dp_clock_recovery_ok);
-u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
+u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
int lane)
{
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
@@ -290,7 +290,7 @@ u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
}
EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage);
-u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
+u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
int lane)
{
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
@@ -303,7 +303,7 @@ u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SI
}
EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
-void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
+void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(100);
else
@@ -311,7 +311,7 @@ void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
}
EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
-void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
+void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(400);
else
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index d9137e4..fe58d08 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -69,7 +69,6 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
@@ -171,6 +170,76 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
+/**
+ * drm_legacy_dev_reinit
+ *
+ * Reinitializes a legacy/ums drm device in it's lastclose function.
+ */
+static void drm_legacy_dev_reinit(struct drm_device *dev)
+{
+ int i;
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
+ atomic_set(&dev->ioctl_count, 0);
+ atomic_set(&dev->vma_count, 0);
+
+ for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
+ atomic_set(&dev->counts[i], 0);
+
+ dev->sigdata.lock = NULL;
+
+ dev->context_flag = 0;
+ dev->last_context = 0;
+ dev->if_version = 0;
+}
+
+/**
+ * Take down the DRM device.
+ *
+ * \param dev DRM device structure.
+ *
+ * Frees every resource in \p dev.
+ *
+ * \sa drm_device
+ */
+int drm_lastclose(struct drm_device * dev)
+{
+ struct drm_vma_entry *vma, *vma_temp;
+
+ DRM_DEBUG("\n");
+
+ if (dev->driver->lastclose)
+ dev->driver->lastclose(dev);
+ DRM_DEBUG("driver lastclose completed\n");
+
+ if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_irq_uninstall(dev);
+
+ mutex_lock(&dev->struct_mutex);
+
+ drm_agp_clear(dev);
+
+ drm_legacy_sg_cleanup(dev);
+
+ /* Clear vma list (only built for debugging) */
+ list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
+ list_del(&vma->head);
+ kfree(vma);
+ }
+
+ drm_legacy_dma_takedown(dev);
+
+ dev->dev_mapping = NULL;
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_legacy_dev_reinit(dev);
+
+ DRM_DEBUG("lastclose completed\n");
+ return 0;
+}
+
/** File operations structure */
static const struct file_operations drm_stub_fops = {
.owner = THIS_MODULE,
@@ -316,6 +385,7 @@ long drm_ioctl(struct file *filp,
return -ENODEV;
atomic_inc(&dev->ioctl_count);
+ atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
++file_priv->ioctl_count;
if ((nr >= DRM_CORE_IOCTL_COUNT) &&
@@ -403,7 +473,7 @@ long drm_ioctl(struct file *filp,
err_i1:
if (!ioctl)
- DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
+ DRM_DEBUG("invalid iotcl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
task_pid_nr(current),
(long)old_encode_dev(file_priv->minor->device),
file_priv->authenticated, cmd, nr);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0a1e4a5..830f750 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -458,15 +458,6 @@ static const struct drm_display_mode drm_dmt_modes[] = {
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
};
-/*
- * These more or less come from the DMT spec. The 720x400 modes are
- * inferred from historical 80x25 practice. The 640x480@67 and 832x624@75
- * modes are old-school Mac modes. The EDID spec says the 1152x864@75 mode
- * should be 1152x870, again for the Mac, but instead we use the x864 DMT
- * mode.
- *
- * The DMT modes have been fact-checked; the rest are mild guesses.
- */
static const struct drm_display_mode edid_est_modes[] = {
{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
968, 1056, 0, 600, 601, 605, 628, 0,
@@ -569,7 +560,7 @@ static const struct minimode est3_modes[] = {
{ 1600, 1200, 75, 0 },
{ 1600, 1200, 85, 0 },
{ 1792, 1344, 60, 0 },
- { 1792, 1344, 75, 0 },
+ { 1792, 1344, 85, 0 },
{ 1856, 1392, 60, 0 },
{ 1856, 1392, 75, 0 },
{ 1920, 1200, 60, 1 },
@@ -1273,18 +1264,6 @@ struct edid *drm_get_edid(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_get_edid);
-/**
- * drm_edid_duplicate - duplicate an EDID and the extensions
- * @edid: EDID to duplicate
- *
- * Return duplicate edid or NULL on allocation failure.
- */
-struct edid *drm_edid_duplicate(const struct edid *edid)
-{
- return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
-}
-EXPORT_SYMBOL(drm_edid_duplicate);
-
/*** EDID parsing ***/
/**
@@ -1329,7 +1308,7 @@ static u32 edid_get_quirks(struct edid *edid)
}
#define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
-#define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))
+#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh))
/**
* edid_fixup_preferred - set preferred modes based on quirk list
@@ -1344,7 +1323,6 @@ static void edid_fixup_preferred(struct drm_connector *connector,
{
struct drm_display_mode *t, *cur_mode, *preferred_mode;
int target_refresh = 0;
- int cur_vrefresh, preferred_vrefresh;
if (list_empty(&connector->probed_modes))
return;
@@ -1367,14 +1345,10 @@ static void edid_fixup_preferred(struct drm_connector *connector,
if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
preferred_mode = cur_mode;
- cur_vrefresh = cur_mode->vrefresh ?
- cur_mode->vrefresh : drm_mode_vrefresh(cur_mode);
- preferred_vrefresh = preferred_mode->vrefresh ?
- preferred_mode->vrefresh : drm_mode_vrefresh(preferred_mode);
/* At a given size, try to get closest to target refresh */
if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
- MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) <
- MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) {
+ MODE_REFRESH_DIFF(cur_mode, target_refresh) <
+ MODE_REFRESH_DIFF(preferred_mode, target_refresh)) {
preferred_mode = cur_mode;
}
}
@@ -2094,7 +2068,7 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing)
u8 *est = ((u8 *)timing) + 5;
for (i = 0; i < 6; i++) {
- for (j = 7; j >= 0; j--) {
+ for (j = 7; j > 0; j--) {
m = (i * 8) + (7 - j);
if (m >= ARRAY_SIZE(est3_modes))
break;
@@ -2430,7 +2404,7 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
- drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode))
+ drm_mode_equal_no_clocks(to_match, cea_mode))
return mode + 1;
}
return 0;
@@ -2479,7 +2453,7 @@ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
- drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode))
+ drm_mode_equal_no_clocks(to_match, hdmi_mode))
return mode + 1;
}
return 0;
@@ -2533,9 +2507,6 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
if (!newmode)
continue;
- /* Carry over the stereo flags */
- newmode->flags |= mode->flags & DRM_MODE_FLAG_3D_MASK;
-
/*
* The current mode could be either variant. Make
* sure to pick the "other" clock for the new mode.
@@ -2582,151 +2553,20 @@ do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
return modes;
}
-struct stereo_mandatory_mode {
- int width, height, vrefresh;
- unsigned int flags;
-};
-
-static const struct stereo_mandatory_mode stereo_mandatory_modes[] = {
- { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
- { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING },
- { 1920, 1080, 50,
- DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
- { 1920, 1080, 60,
- DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
- { 1280, 720, 50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
- { 1280, 720, 50, DRM_MODE_FLAG_3D_FRAME_PACKING },
- { 1280, 720, 60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
- { 1280, 720, 60, DRM_MODE_FLAG_3D_FRAME_PACKING }
-};
-
-static bool
-stereo_match_mandatory(const struct drm_display_mode *mode,
- const struct stereo_mandatory_mode *stereo_mode)
-{
- unsigned int interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
-
- return mode->hdisplay == stereo_mode->width &&
- mode->vdisplay == stereo_mode->height &&
- interlaced == (stereo_mode->flags & DRM_MODE_FLAG_INTERLACE) &&
- drm_mode_vrefresh(mode) == stereo_mode->vrefresh;
-}
-
-static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- const struct drm_display_mode *mode;
- struct list_head stereo_modes;
- int modes = 0, i;
-
- INIT_LIST_HEAD(&stereo_modes);
-
- list_for_each_entry(mode, &connector->probed_modes, head) {
- for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) {
- const struct stereo_mandatory_mode *mandatory;
- struct drm_display_mode *new_mode;
-
- if (!stereo_match_mandatory(mode,
- &stereo_mandatory_modes[i]))
- continue;
-
- mandatory = &stereo_mandatory_modes[i];
- new_mode = drm_mode_duplicate(dev, mode);
- if (!new_mode)
- continue;
-
- new_mode->flags |= mandatory->flags;
- list_add_tail(&new_mode->head, &stereo_modes);
- modes++;
- }
- }
-
- list_splice_tail(&stereo_modes, &connector->probed_modes);
-
- return modes;
-}
-
-static int add_hdmi_mode(struct drm_connector *connector, u8 vic)
-{
- struct drm_device *dev = connector->dev;
- struct drm_display_mode *newmode;
-
- vic--; /* VICs start at 1 */
- if (vic >= ARRAY_SIZE(edid_4k_modes)) {
- DRM_ERROR("Unknown HDMI VIC: %d\n", vic);
- return 0;
- }
-
- newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]);
- if (!newmode)
- return 0;
-
- drm_mode_probed_add(connector, newmode);
-
- return 1;
-}
-
-static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
- const u8 *video_db, u8 video_len, u8 video_index)
-{
- struct drm_device *dev = connector->dev;
- struct drm_display_mode *newmode;
- int modes = 0;
- u8 cea_mode;
-
- if (video_db == NULL || video_index >= video_len)
- return 0;
-
- /* CEA modes are numbered 1..127 */
- cea_mode = (video_db[video_index] & 127) - 1;
- if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
- return 0;
-
- if (structure & (1 << 0)) {
- newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]);
- if (newmode) {
- newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
- drm_mode_probed_add(connector, newmode);
- modes++;
- }
- }
- if (structure & (1 << 6)) {
- newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]);
- if (newmode) {
- newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
- drm_mode_probed_add(connector, newmode);
- modes++;
- }
- }
- if (structure & (1 << 8)) {
- newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]);
- if (newmode) {
- newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
- drm_mode_probed_add(connector, newmode);
- modes++;
- }
- }
-
- return modes;
-}
-
/*
* do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
* @connector: connector corresponding to the HDMI sink
* @db: start of the CEA vendor specific block
* @len: length of the CEA block payload, ie. one can access up to db[len]
*
- * Parses the HDMI VSDB looking for modes to add to @connector. This function
- * also adds the stereo 3d modes when applicable.
+ * Parses the HDMI VSDB looking for modes to add to @connector.
*/
static int
-do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
- const u8 *video_db, u8 video_len)
+do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
{
- int modes = 0, offset = 0, i, multi_present = 0;
- u8 vic_len, hdmi_3d_len = 0;
- u16 mask;
- u16 structure_all;
+ struct drm_device *dev = connector->dev;
+ int modes = 0, offset = 0, i;
+ u8 vic_len;
if (len < 8)
goto out;
@@ -2745,56 +2585,30 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
/* the declared length is not long enough for the 2 first bytes
* of additional video format capabilities */
- if (len < (8 + offset + 2))
+ offset += 2;
+ if (len < (8 + offset))
goto out;
- /* 3D_Present */
- offset++;
- if (db[8 + offset] & (1 << 7)) {
- modes += add_hdmi_mandatory_stereo_modes(connector);
-
- /* 3D_Multi_present */
- multi_present = (db[8 + offset] & 0x60) >> 5;
- }
-
- offset++;
vic_len = db[8 + offset] >> 5;
- hdmi_3d_len = db[8 + offset] & 0x1f;
for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
+ struct drm_display_mode *newmode;
u8 vic;
vic = db[9 + offset + i];
- modes += add_hdmi_mode(connector, vic);
- }
- offset += 1 + vic_len;
-
- if (!(multi_present == 1 || multi_present == 2))
- goto out;
-
- if ((multi_present == 1 && len < (9 + offset)) ||
- (multi_present == 2 && len < (11 + offset)))
- goto out;
- if ((multi_present == 1 && hdmi_3d_len < 2) ||
- (multi_present == 2 && hdmi_3d_len < 4))
- goto out;
-
- /* 3D_Structure_ALL */
- structure_all = (db[8 + offset] << 8) | db[9 + offset];
+ vic--; /* VICs start at 1 */
+ if (vic >= ARRAY_SIZE(edid_4k_modes)) {
+ DRM_ERROR("Unknown HDMI VIC: %d\n", vic);
+ continue;
+ }
- /* check if 3D_MASK is present */
- if (multi_present == 2)
- mask = (db[10 + offset] << 8) | db[11 + offset];
- else
- mask = 0xffff;
+ newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]);
+ if (!newmode)
+ continue;
- for (i = 0; i < 16; i++) {
- if (mask & (1 << i))
- modes += add_3d_struct_modes(connector,
- structure_all,
- video_db,
- video_len, i);
+ drm_mode_probed_add(connector, newmode);
+ modes++;
}
out:
@@ -2854,8 +2668,8 @@ static int
add_cea_modes(struct drm_connector *connector, struct edid *edid)
{
const u8 *cea = drm_find_cea_extension(edid);
- const u8 *db, *hdmi = NULL, *video = NULL;
- u8 dbl, hdmi_len, video_len = 0;
+ const u8 *db;
+ u8 dbl;
int modes = 0;
if (cea && cea_revision(cea) >= 3) {
@@ -2868,26 +2682,13 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
db = &cea[i];
dbl = cea_db_payload_len(db);
- if (cea_db_tag(db) == VIDEO_BLOCK) {
- video = db + 1;
- video_len = dbl;
- modes += do_cea_modes(connector, video, dbl);
- }
- else if (cea_db_is_hdmi_vsdb(db)) {
- hdmi = db;
- hdmi_len = dbl;
- }
+ if (cea_db_tag(db) == VIDEO_BLOCK)
+ modes += do_cea_modes(connector, db + 1, dbl);
+ else if (cea_db_is_hdmi_vsdb(db))
+ modes += do_hdmi_vsdb_modes(connector, db, dbl);
}
}
- /*
- * We parse the HDMI VSDB after having added the cea modes as we will
- * be patching their flags when the sink supports stereo 3D.
- */
- if (hdmi)
- modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
- video_len);
-
return modes;
}
@@ -3487,19 +3288,6 @@ int drm_add_modes_noedid(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_add_modes_noedid);
-void drm_set_preferred_mode(struct drm_connector *connector,
- int hpref, int vpref)
-{
- struct drm_display_mode *mode;
-
- list_for_each_entry(mode, &connector->probed_modes, head) {
- if (drm_mode_width(mode) == hpref &&
- drm_mode_height(mode) == vpref)
- mode->type |= DRM_MODE_TYPE_PREFERRED;
- }
-}
-EXPORT_SYMBOL(drm_set_preferred_mode);
-
/**
* drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
* data from a DRM display mode
@@ -3533,33 +3321,6 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
}
EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
-static enum hdmi_3d_structure
-s3d_structure_from_display_mode(const struct drm_display_mode *mode)
-{
- u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK;
-
- switch (layout) {
- case DRM_MODE_FLAG_3D_FRAME_PACKING:
- return HDMI_3D_STRUCTURE_FRAME_PACKING;
- case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
- return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE;
- case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
- return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE;
- case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
- return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL;
- case DRM_MODE_FLAG_3D_L_DEPTH:
- return HDMI_3D_STRUCTURE_L_DEPTH;
- case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
- return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH;
- case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
- return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM;
- case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
- return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF;
- default:
- return HDMI_3D_STRUCTURE_INVALID;
- }
-}
-
/**
* drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with
* data from a DRM display mode
@@ -3577,29 +3338,20 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
const struct drm_display_mode *mode)
{
int err;
- u32 s3d_flags;
u8 vic;
if (!frame || !mode)
return -EINVAL;
vic = drm_match_hdmi_mode(mode);
- s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK;
-
- if (!vic && !s3d_flags)
- return -EINVAL;
-
- if (vic && s3d_flags)
+ if (!vic)
return -EINVAL;
err = hdmi_vendor_infoframe_init(frame);
if (err < 0)
return err;
- if (vic)
- frame->vic = vic;
- else
- frame->s3d_struct = s3d_structure_from_display_mode(mode);
+ frame->vic = vic;
return 0;
}
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index 9081172..271b42b 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -32,7 +32,7 @@ MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob "
"from built-in data or /lib/firmware instead. ");
#define GENERIC_EDIDS 5
-static const char *generic_edid_name[GENERIC_EDIDS] = {
+static char *generic_edid_name[GENERIC_EDIDS] = {
"edid/1024x768.bin",
"edid/1280x1024.bin",
"edid/1600x1200.bin",
@@ -40,7 +40,7 @@ static const char *generic_edid_name[GENERIC_EDIDS] = {
"edid/1920x1080.bin",
};
-static const u8 generic_edid[GENERIC_EDIDS][128] = {
+static u8 generic_edid[GENERIC_EDIDS][128] = {
{
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -133,68 +133,63 @@ static const u8 generic_edid[GENERIC_EDIDS][128] = {
},
};
-static int edid_size(const u8 *edid, int data_size)
-{
- if (data_size < EDID_LENGTH)
- return 0;
-
- return (edid[0x7e] + 1) * EDID_LENGTH;
-}
-
static u8 *edid_load(struct drm_connector *connector, const char *name,
const char *connector_name)
{
- const struct firmware *fw = NULL;
- const u8 *fwdata;
- u8 *edid;
- int fwsize, builtin;
+ const struct firmware *fw;
+ struct platform_device *pdev;
+ u8 *fwdata = NULL, *edid, *new_edid;
+ int fwsize, expected;
+ int builtin = 0, err = 0;
int i, valid_extensions = 0;
bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
- builtin = 0;
- for (i = 0; i < GENERIC_EDIDS; i++) {
- if (strcmp(name, generic_edid_name[i]) == 0) {
+ pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ DRM_ERROR("Failed to register EDID firmware platform device "
+ "for connector \"%s\"\n", connector_name);
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = request_firmware(&fw, name, &pdev->dev);
+ platform_device_unregister(pdev);
+
+ if (err) {
+ i = 0;
+ while (i < GENERIC_EDIDS && strcmp(name, generic_edid_name[i]))
+ i++;
+ if (i < GENERIC_EDIDS) {
+ err = 0;
+ builtin = 1;
fwdata = generic_edid[i];
fwsize = sizeof(generic_edid[i]);
- builtin = 1;
- break;
}
}
- if (!builtin) {
- struct platform_device *pdev;
- int err;
-
- pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
- if (IS_ERR(pdev)) {
- DRM_ERROR("Failed to register EDID firmware platform device "
- "for connector \"%s\"\n", connector_name);
- return ERR_CAST(pdev);
- }
- err = request_firmware(&fw, name, &pdev->dev);
- platform_device_unregister(pdev);
- if (err) {
- DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
- name, err);
- return ERR_PTR(err);
- }
+ if (err) {
+ DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
+ name, err);
+ goto out;
+ }
- fwdata = fw->data;
+ if (fwdata == NULL) {
+ fwdata = (u8 *) fw->data;
fwsize = fw->size;
}
- if (edid_size(fwdata, fwsize) != fwsize) {
+ expected = (fwdata[0x7e] + 1) * EDID_LENGTH;
+ if (expected != fwsize) {
DRM_ERROR("Size of EDID firmware \"%s\" is invalid "
- "(expected %d, got %d\n", name,
- edid_size(fwdata, fwsize), (int)fwsize);
- edid = ERR_PTR(-EINVAL);
- goto out;
+ "(expected %d, got %d)\n", name, expected, (int) fwsize);
+ err = -EINVAL;
+ goto relfw_out;
}
edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
if (edid == NULL) {
- edid = ERR_PTR(-ENOMEM);
- goto out;
+ err = -ENOMEM;
+ goto relfw_out;
}
if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
@@ -202,8 +197,8 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
name);
kfree(edid);
- edid = ERR_PTR(-EINVAL);
- goto out;
+ err = -EINVAL;
+ goto relfw_out;
}
for (i = 1; i <= edid[0x7e]; i++) {
@@ -215,18 +210,19 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
}
if (valid_extensions != edid[0x7e]) {
- u8 *new_edid;
-
edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
DRM_INFO("Found %d valid extensions instead of %d in EDID data "
"\"%s\" for connector \"%s\"\n", valid_extensions,
edid[0x7e], name, connector_name);
edid[0x7e] = valid_extensions;
-
new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
- GFP_KERNEL);
- if (new_edid)
- edid = new_edid;
+ GFP_KERNEL);
+ if (new_edid == NULL) {
+ err = -ENOMEM;
+ kfree(edid);
+ goto relfw_out;
+ }
+ edid = new_edid;
}
DRM_INFO("Got %s EDID base block and %d extension%s from "
@@ -234,9 +230,13 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
"external", valid_extensions, valid_extensions == 1 ? "" : "s",
name, connector_name);
+relfw_out:
+ release_firmware(fw);
+
out:
- if (fw)
- release_firmware(fw);
+ if (err)
+ return ERR_PTR(err);
+
return edid;
}
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c
index d18b88b..0cfb60f 100644
--- a/drivers/gpu/drm/drm_encoder_slave.c
+++ b/drivers/gpu/drm/drm_encoder_slave.c
@@ -67,12 +67,12 @@ int drm_i2c_encoder_init(struct drm_device *dev,
goto fail;
}
- if (!client->dev.driver) {
+ if (!client->driver) {
err = -ENODEV;
goto fail_unregister;
}
- module = client->dev.driver->owner;
+ module = client->driver->driver.owner;
if (!try_module_get(module)) {
err = -ENODEV;
goto fail_unregister;
@@ -80,7 +80,7 @@ int drm_i2c_encoder_init(struct drm_device *dev,
encoder->bus_priv = client;
- encoder_drv = to_drm_i2c_encoder_driver(to_i2c_driver(client->dev.driver));
+ encoder_drv = to_drm_i2c_encoder_driver(client->driver);
err = encoder_drv->encoder_init(client, dev, encoder);
if (err)
@@ -111,7 +111,7 @@ void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
{
struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
- struct module *module = client->dev.driver->owner;
+ struct module *module = client->driver->driver.owner;
i2c_unregister_device(client);
encoder->bus_priv = NULL;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 0a19401..3d13ca6e2 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -39,6 +39,10 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h>
+MODULE_AUTHOR("David Airlie, Jesse Barnes");
+MODULE_DESCRIPTION("DRM KMS helper");
+MODULE_LICENSE("GPL and additional rights");
+
static LIST_HEAD(kernel_fb_helper_list);
/**
@@ -840,6 +844,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
struct drm_fb_helper *fb_helper = info->par;
struct drm_device *dev = fb_helper->dev;
struct drm_mode_set *modeset;
+ struct drm_crtc *crtc;
int ret = 0;
int i;
@@ -850,6 +855,8 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
}
for (i = 0; i < fb_helper->crtc_count; i++) {
+ crtc = fb_helper->crtc_info[i].mode_set.crtc;
+
modeset = &fb_helper->crtc_info[i].mode_set;
modeset->x = var->xoffset;
@@ -1345,6 +1352,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
struct drm_connector *connector;
struct drm_connector_helper_funcs *connector_funcs;
struct drm_encoder *encoder;
+ struct drm_fb_helper_crtc *best_crtc;
int my_score, best_score, score;
struct drm_fb_helper_crtc **crtcs, *crtc;
struct drm_fb_helper_connector *fb_helper_conn;
@@ -1356,6 +1364,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
connector = fb_helper_conn->connector;
best_crtcs[n] = NULL;
+ best_crtc = NULL;
best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height);
if (modes[n] == NULL)
return best_score;
@@ -1404,6 +1413,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1,
width, height);
if (score > best_score) {
+ best_crtc = crtc;
best_score = score;
memcpy(best_crtcs, crtcs,
dev->mode_config.num_connector *
@@ -1570,7 +1580,8 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
- u32 max_width, max_height;
+ int count = 0;
+ u32 max_width, max_height, bpp_sel;
if (!fb_helper->fb)
return 0;
@@ -1585,8 +1596,10 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
max_width = fb_helper->fb->width;
max_height = fb_helper->fb->height;
+ bpp_sel = fb_helper->fb->bits_per_pixel;
- drm_fb_helper_probe_connector_modes(fb_helper, max_width, max_height);
+ count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
+ max_height);
mutex_unlock(&fb_helper->dev->mode_config.mutex);
drm_modeset_lock_all(dev);
diff --git a/drivers/gpu/drm/drm_flip_work.c b/drivers/gpu/drm/drm_flip_work.c
index f9c7fa3..e788882 100644
--- a/drivers/gpu/drm/drm_flip_work.c
+++ b/drivers/gpu/drm/drm_flip_work.c
@@ -34,7 +34,7 @@
*/
void drm_flip_work_queue(struct drm_flip_work *work, void *val)
{
- if (kfifo_put(&work->fifo, val)) {
+ if (kfifo_put(&work->fifo, (const void **)&val)) {
atomic_inc(&work->pending);
} else {
DRM_ERROR("%s fifo full!\n", work->name);
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index c5b929c..3f84277 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -113,6 +113,7 @@ int drm_open(struct inode *inode, struct file *filp)
retcode = drm_open_helper(inode, filp, dev);
if (retcode)
goto err_undo;
+ atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
if (need_setup) {
retcode = drm_setup(dev);
if (retcode)
@@ -147,7 +148,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
struct drm_minor *minor;
int minor_id = iminor(inode);
int err = -ENODEV;
- const struct file_operations *new_fops;
+ const struct file_operations *old_fops;
DRM_DEBUG("\n");
@@ -162,13 +163,18 @@ int drm_stub_open(struct inode *inode, struct file *filp)
if (drm_device_is_unplugged(dev))
goto out;
- new_fops = fops_get(dev->driver->fops);
- if (!new_fops)
+ old_fops = filp->f_op;
+ filp->f_op = fops_get(dev->driver->fops);
+ if (filp->f_op == NULL) {
+ filp->f_op = old_fops;
goto out;
+ }
+ if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
+ fops_put(filp->f_op);
+ filp->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
- replace_fops(filp, new_fops);
- if (filp->f_op->open)
- err = filp->f_op->open(inode, filp);
out:
mutex_unlock(&drm_global_mutex);
return err;
@@ -234,8 +240,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
priv->ioctl_count = 0;
/* for compatibility root is always authenticated */
- priv->always_authenticated = capable(CAP_SYS_ADMIN);
- priv->authenticated = priv->always_authenticated;
+ priv->authenticated = capable(CAP_SYS_ADMIN);
priv->lock_count = 0;
INIT_LIST_HEAD(&priv->lhead);
@@ -374,80 +379,13 @@ static void drm_events_release(struct drm_file *file_priv)
}
/* Remove unconsumed events */
- list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
- list_del(&e->link);
+ list_for_each_entry_safe(e, et, &file_priv->event_list, link)
e->destroy(e);
- }
spin_unlock_irqrestore(&dev->event_lock, flags);
}
/**
- * drm_legacy_dev_reinit
- *
- * Reinitializes a legacy/ums drm device in it's lastclose function.
- */
-static void drm_legacy_dev_reinit(struct drm_device *dev)
-{
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- return;
-
- atomic_set(&dev->ioctl_count, 0);
- atomic_set(&dev->vma_count, 0);
-
- dev->sigdata.lock = NULL;
-
- dev->context_flag = 0;
- dev->last_context = 0;
- dev->if_version = 0;
-}
-
-/**
- * Take down the DRM device.
- *
- * \param dev DRM device structure.
- *
- * Frees every resource in \p dev.
- *
- * \sa drm_device
- */
-int drm_lastclose(struct drm_device * dev)
-{
- struct drm_vma_entry *vma, *vma_temp;
-
- DRM_DEBUG("\n");
-
- if (dev->driver->lastclose)
- dev->driver->lastclose(dev);
- DRM_DEBUG("driver lastclose completed\n");
-
- if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
- drm_irq_uninstall(dev);
-
- mutex_lock(&dev->struct_mutex);
-
- drm_agp_clear(dev);
-
- drm_legacy_sg_cleanup(dev);
-
- /* Clear vma list (only built for debugging) */
- list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
- list_del(&vma->head);
- kfree(vma);
- }
-
- drm_legacy_dma_takedown(dev);
-
- dev->dev_mapping = NULL;
- mutex_unlock(&dev->struct_mutex);
-
- drm_legacy_dev_reinit(dev);
-
- DRM_DEBUG("lastclose completed\n");
- return 0;
-}
-
-/**
* Release file.
*
* \param inode device inode
@@ -516,6 +454,7 @@ int drm_release(struct inode *inode, struct file *filp)
list_del(&pos->head);
kfree(pos);
+ --dev->ctx_count;
}
}
}
@@ -529,7 +468,7 @@ int drm_release(struct inode *inode, struct file *filp)
list_for_each_entry(temp, &dev->filelist, lhead) {
if ((temp->master == file_priv->master) &&
(temp != file_priv))
- temp->authenticated = temp->always_authenticated;
+ temp->authenticated = 0;
}
/**
@@ -577,6 +516,7 @@ int drm_release(struct inode *inode, struct file *filp)
* End inline drm_release
*/
+ atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
if (!--dev->open_count) {
if (atomic_read(&dev->ioctl_count)) {
DRM_ERROR("Device busy: %d\n",
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 4761ade..49293bdc 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -160,6 +160,35 @@ void drm_gem_private_object_init(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_gem_private_object_init);
+/**
+ * Allocate a GEM object of the specified size with shmfs backing store
+ */
+struct drm_gem_object *
+drm_gem_object_alloc(struct drm_device *dev, size_t size)
+{
+ struct drm_gem_object *obj;
+
+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+ if (!obj)
+ goto free;
+
+ if (drm_gem_object_init(dev, obj, size) != 0)
+ goto free;
+
+ if (dev->driver->gem_init_object != NULL &&
+ dev->driver->gem_init_object(obj) != 0) {
+ goto fput;
+ }
+ return obj;
+fput:
+ /* Object_init mangles the global counters - readjust them. */
+ fput(obj->filp);
+free:
+ kfree(obj);
+ return NULL;
+}
+EXPORT_SYMBOL(drm_gem_object_alloc);
+
static void
drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
{
diff --git a/drivers/gpu/drm/drm_global.c b/drivers/gpu/drm/drm_global.c
index 3d2e91c..f731116 100644
--- a/drivers/gpu/drm/drm_global.c
+++ b/drivers/gpu/drm/drm_global.c
@@ -67,6 +67,7 @@ int drm_global_item_ref(struct drm_global_reference *ref)
{
int ret;
struct drm_global_item *item = &glob[ref->global_type];
+ void *object;
mutex_lock(&item->mutex);
if (item->refcount == 0) {
@@ -84,6 +85,7 @@ int drm_global_item_ref(struct drm_global_reference *ref)
}
++item->refcount;
ref->object = item->object;
+ object = item->object;
mutex_unlock(&item->mutex);
return 0;
out_err:
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 7d5a152..5329832 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -163,13 +163,13 @@ int drm_vblank_info(struct seq_file *m, void *data)
mutex_lock(&dev->struct_mutex);
for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
seq_printf(m, "CRTC %d enable: %d\n",
- crtc, atomic_read(&dev->vblank[crtc].refcount));
+ crtc, atomic_read(&dev->vblank_refcount[crtc]));
seq_printf(m, "CRTC %d counter: %d\n",
crtc, drm_vblank_count(dev, crtc));
seq_printf(m, "CRTC %d last wait: %d\n",
- crtc, dev->vblank[crtc].last_wait);
+ crtc, dev->last_vblank_wait[crtc]);
seq_printf(m, "CRTC %d in modeset: %d\n",
- crtc, dev->vblank[crtc].inmodeset);
+ crtc, dev->vblank_inmodeset[crtc]);
}
mutex_unlock(&dev->struct_mutex);
return 0;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index dffc836..07247e2 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -303,27 +303,6 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
}
/**
- * Set device/driver capabilities
- */
-int
-drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_set_client_cap *req = data;
-
- switch (req->capability) {
- case DRM_CLIENT_CAP_STEREO_3D:
- if (req->value > 1)
- return -EINVAL;
- file_priv->stereo_allowed = req->value;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
* Setversion ioctl.
*
* \param inode device inode.
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 64c34d5..f92da0a 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -43,8 +43,9 @@
#include <linux/export.h>
/* Access macro for slots in vblank timestamp ringbuffer. */
-#define vblanktimestamp(dev, crtc, count) \
- ((dev)->vblank[crtc].time[(count) % DRM_VBLANKTIME_RBSIZE])
+#define vblanktimestamp(dev, crtc, count) ( \
+ (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \
+ ((count) % DRM_VBLANKTIME_RBSIZE)])
/* Retry timestamp calculation up to 3 times to satisfy
* drm_timestamp_precision before giving up.
@@ -88,7 +89,8 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
*/
static void clear_vblank_timestamps(struct drm_device *dev, int crtc)
{
- memset(dev->vblank[crtc].time, 0, sizeof(dev->vblank[crtc].time));
+ memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0,
+ DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval));
}
/*
@@ -113,7 +115,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
dev->driver->disable_vblank(dev, crtc);
- dev->vblank[crtc].enabled = false;
+ dev->vblank_enabled[crtc] = 0;
/* No further vblank irq's will be processed after
* this point. Get current hardware vblank count and
@@ -128,9 +130,9 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
* delayed gpu counter increment.
*/
do {
- dev->vblank[crtc].last = dev->driver->get_vblank_counter(dev, crtc);
+ dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0);
- } while (dev->vblank[crtc].last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc);
+ } while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc);
if (!count)
vblrc = 0;
@@ -138,7 +140,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
/* Compute time difference to stored timestamp of last vblank
* as updated by last invocation of drm_handle_vblank() in vblank irq.
*/
- vblcount = atomic_read(&dev->vblank[crtc].count);
+ vblcount = atomic_read(&dev->_vblank_count[crtc]);
diff_ns = timeval_to_ns(&tvblank) -
timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
@@ -155,7 +157,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
* hope for the best.
*/
if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) {
- atomic_inc(&dev->vblank[crtc].count);
+ atomic_inc(&dev->_vblank_count[crtc]);
smp_mb__after_atomic_inc();
}
@@ -176,8 +178,8 @@ static void vblank_disable_fn(unsigned long arg)
for (i = 0; i < dev->num_crtcs; i++) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
- if (atomic_read(&dev->vblank[i].refcount) == 0 &&
- dev->vblank[i].enabled) {
+ if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
+ dev->vblank_enabled[i]) {
DRM_DEBUG("disabling vblank on crtc %d\n", i);
vblank_disable_and_save(dev, i);
}
@@ -195,7 +197,14 @@ void drm_vblank_cleanup(struct drm_device *dev)
vblank_disable_fn((unsigned long)dev);
- kfree(dev->vblank);
+ kfree(dev->vbl_queue);
+ kfree(dev->_vblank_count);
+ kfree(dev->vblank_refcount);
+ kfree(dev->vblank_enabled);
+ kfree(dev->last_vblank);
+ kfree(dev->last_vblank_wait);
+ kfree(dev->vblank_inmodeset);
+ kfree(dev->_vblank_time);
dev->num_crtcs = 0;
}
@@ -212,14 +221,42 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
dev->num_crtcs = num_crtcs;
- dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
- if (!dev->vblank)
+ dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs,
+ GFP_KERNEL);
+ if (!dev->vbl_queue)
goto err;
- for (i = 0; i < num_crtcs; i++)
- init_waitqueue_head(&dev->vblank[i].queue);
+ dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, GFP_KERNEL);
+ if (!dev->_vblank_count)
+ goto err;
+
+ dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs,
+ GFP_KERNEL);
+ if (!dev->vblank_refcount)
+ goto err;
+
+ dev->vblank_enabled = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
+ if (!dev->vblank_enabled)
+ goto err;
- DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
+ dev->last_vblank = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
+ if (!dev->last_vblank)
+ goto err;
+
+ dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
+ if (!dev->last_vblank_wait)
+ goto err;
+
+ dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
+ if (!dev->vblank_inmodeset)
+ goto err;
+
+ dev->_vblank_time = kcalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE,
+ sizeof(struct timeval), GFP_KERNEL);
+ if (!dev->_vblank_time)
+ goto err;
+
+ DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n");
/* Driver specific high-precision vblank timestamping supported? */
if (dev->driver->get_vblank_timestamp)
@@ -227,8 +264,14 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
else
DRM_INFO("No driver support for vblank timestamp query.\n");
- dev->vblank_disable_allowed = false;
+ /* Zero per-crtc vblank stuff */
+ for (i = 0; i < num_crtcs; i++) {
+ init_waitqueue_head(&dev->vbl_queue[i]);
+ atomic_set(&dev->_vblank_count[i], 0);
+ atomic_set(&dev->vblank_refcount[i], 0);
+ }
+ dev->vblank_disable_allowed = 0;
return 0;
err:
@@ -293,7 +336,7 @@ int drm_irq_install(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex);
return -EBUSY;
}
- dev->irq_enabled = true;
+ dev->irq_enabled = 1;
mutex_unlock(&dev->struct_mutex);
DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
@@ -316,7 +359,7 @@ int drm_irq_install(struct drm_device *dev)
if (ret < 0) {
mutex_lock(&dev->struct_mutex);
- dev->irq_enabled = false;
+ dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
return ret;
}
@@ -330,7 +373,7 @@ int drm_irq_install(struct drm_device *dev)
if (ret < 0) {
mutex_lock(&dev->struct_mutex);
- dev->irq_enabled = false;
+ dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
if (!drm_core_check_feature(dev, DRIVER_MODESET))
vga_client_register(dev->pdev, NULL, NULL, NULL);
@@ -351,15 +394,14 @@ EXPORT_SYMBOL(drm_irq_install);
int drm_irq_uninstall(struct drm_device *dev)
{
unsigned long irqflags;
- bool irq_enabled;
- int i;
+ int irq_enabled, i;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
mutex_lock(&dev->struct_mutex);
irq_enabled = dev->irq_enabled;
- dev->irq_enabled = false;
+ dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
/*
@@ -368,9 +410,9 @@ int drm_irq_uninstall(struct drm_device *dev)
if (dev->num_crtcs) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
for (i = 0; i < dev->num_crtcs; i++) {
- DRM_WAKEUP(&dev->vblank[i].queue);
- dev->vblank[i].enabled = false;
- dev->vblank[i].last =
+ DRM_WAKEUP(&dev->vbl_queue[i]);
+ dev->vblank_enabled[i] = 0;
+ dev->last_vblank[i] =
dev->driver->get_vblank_counter(dev, i);
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -455,8 +497,8 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc)
/* Dot clock in Hz: */
dotclock = (u64) crtc->hwmode.clock * 1000;
- /* Fields of interlaced scanout modes are only half a frame duration.
- * Double the dotclock to get half the frame-/line-/pixelduration.
+ /* Fields of interlaced scanout modes are only halve a frame duration.
+ * Double the dotclock to get halve the frame-/line-/pixelduration.
*/
if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE)
dotclock *= 2;
@@ -586,20 +628,24 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
* code gets preempted or delayed for some reason.
*/
for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) {
- /*
- * Get vertical and horizontal scanout position vpos, hpos,
- * and bounding timestamps stime, etime, pre/post query.
+ /* Disable preemption to make it very likely to
+ * succeed in the first iteration even on PREEMPT_RT kernel.
*/
- vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos,
- &hpos, &stime, &etime);
+ preempt_disable();
- /*
- * Get correction for CLOCK_MONOTONIC -> CLOCK_REALTIME if
- * CLOCK_REALTIME is requested.
- */
+ /* Get system timestamp before query. */
+ stime = ktime_get();
+
+ /* Get vertical and horizontal scanout pos. vpos, hpos. */
+ vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos);
+
+ /* Get system timestamp after query. */
+ etime = ktime_get();
if (!drm_timestamp_monotonic)
mono_time_offset = ktime_get_monotonic_offset();
+ preempt_enable();
+
/* Return as no-op if scanout query unsupported or failed. */
if (!(vbl_status & DRM_SCANOUTPOS_VALID)) {
DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n",
@@ -607,7 +653,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
return -EIO;
}
- /* Compute uncertainty in timestamp of scanout position query. */
duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime);
/* Accept result with < max_error nsecs timing uncertainty. */
@@ -750,7 +795,7 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp);
*/
u32 drm_vblank_count(struct drm_device *dev, int crtc)
{
- return atomic_read(&dev->vblank[crtc].count);
+ return atomic_read(&dev->_vblank_count[crtc]);
}
EXPORT_SYMBOL(drm_vblank_count);
@@ -779,10 +824,10 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
* a seqlock.
*/
do {
- cur_vblank = atomic_read(&dev->vblank[crtc].count);
+ cur_vblank = atomic_read(&dev->_vblank_count[crtc]);
*vblanktime = vblanktimestamp(dev, crtc, cur_vblank);
smp_rmb();
- } while (cur_vblank != atomic_read(&dev->vblank[crtc].count));
+ } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc]));
return cur_vblank;
}
@@ -869,12 +914,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
} while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
/* Deal with counter wrap */
- diff = cur_vblank - dev->vblank[crtc].last;
- if (cur_vblank < dev->vblank[crtc].last) {
+ diff = cur_vblank - dev->last_vblank[crtc];
+ if (cur_vblank < dev->last_vblank[crtc]) {
diff += dev->max_vblank_count;
DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
- crtc, dev->vblank[crtc].last, cur_vblank, diff);
+ crtc, dev->last_vblank[crtc], cur_vblank, diff);
}
DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
@@ -885,12 +930,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
* reinitialize delayed at next vblank interrupt in that case.
*/
if (rc) {
- tslot = atomic_read(&dev->vblank[crtc].count) + diff;
+ tslot = atomic_read(&dev->_vblank_count[crtc]) + diff;
vblanktimestamp(dev, crtc, tslot) = t_vblank;
}
smp_mb__before_atomic_inc();
- atomic_add(diff, &dev->vblank[crtc].count);
+ atomic_add(diff, &dev->_vblank_count[crtc]);
smp_mb__after_atomic_inc();
}
@@ -912,9 +957,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
- if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) {
+ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
- if (!dev->vblank[crtc].enabled) {
+ if (!dev->vblank_enabled[crtc]) {
/* Enable vblank irqs under vblank_time_lock protection.
* All vblank count & timestamp updates are held off
* until we are done reinitializing master counter and
@@ -925,16 +970,16 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n",
crtc, ret);
if (ret)
- atomic_dec(&dev->vblank[crtc].refcount);
+ atomic_dec(&dev->vblank_refcount[crtc]);
else {
- dev->vblank[crtc].enabled = true;
+ dev->vblank_enabled[crtc] = 1;
drm_update_vblank_count(dev, crtc);
}
}
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
} else {
- if (!dev->vblank[crtc].enabled) {
- atomic_dec(&dev->vblank[crtc].refcount);
+ if (!dev->vblank_enabled[crtc]) {
+ atomic_dec(&dev->vblank_refcount[crtc]);
ret = -EINVAL;
}
}
@@ -954,10 +999,10 @@ EXPORT_SYMBOL(drm_vblank_get);
*/
void drm_vblank_put(struct drm_device *dev, int crtc)
{
- BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0);
+ BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0);
/* Last user schedules interrupt disable */
- if (atomic_dec_and_test(&dev->vblank[crtc].refcount) &&
+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) &&
(drm_vblank_offdelay > 0))
mod_timer(&dev->vblank_disable_timer,
jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000));
@@ -980,7 +1025,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vbl_lock, irqflags);
vblank_disable_and_save(dev, crtc);
- DRM_WAKEUP(&dev->vblank[crtc].queue);
+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
/* Send any queued vblank events, lest the natives grow disquiet */
seq = drm_vblank_count_and_time(dev, crtc, &now);
@@ -1022,10 +1067,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
* to avoid corrupting the count if multiple, mismatch calls occur),
* so that interrupts remain enabled in the interim.
*/
- if (!dev->vblank[crtc].inmodeset) {
- dev->vblank[crtc].inmodeset = 0x1;
+ if (!dev->vblank_inmodeset[crtc]) {
+ dev->vblank_inmodeset[crtc] = 0x1;
if (drm_vblank_get(dev, crtc) == 0)
- dev->vblank[crtc].inmodeset |= 0x2;
+ dev->vblank_inmodeset[crtc] |= 0x2;
}
}
EXPORT_SYMBOL(drm_vblank_pre_modeset);
@@ -1038,15 +1083,15 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
if (!dev->num_crtcs)
return;
- if (dev->vblank[crtc].inmodeset) {
+ if (dev->vblank_inmodeset[crtc]) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
- dev->vblank_disable_allowed = true;
+ dev->vblank_disable_allowed = 1;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- if (dev->vblank[crtc].inmodeset & 0x2)
+ if (dev->vblank_inmodeset[crtc] & 0x2)
drm_vblank_put(dev, crtc);
- dev->vblank[crtc].inmodeset = 0;
+ dev->vblank_inmodeset[crtc] = 0;
}
}
EXPORT_SYMBOL(drm_vblank_post_modeset);
@@ -1243,8 +1288,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
vblwait->request.sequence, crtc);
- dev->vblank[crtc].last_wait = vblwait->request.sequence;
- DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * DRM_HZ,
+ dev->last_vblank_wait[crtc] = vblwait->request.sequence;
+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
(((drm_vblank_count(dev, crtc) -
vblwait->request.sequence) <= (1 << 23)) ||
!dev->irq_enabled));
@@ -1322,7 +1367,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
/* Vblank irq handling disabled. Nothing to do. */
- if (!dev->vblank[crtc].enabled) {
+ if (!dev->vblank_enabled[crtc]) {
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
return false;
}
@@ -1332,7 +1377,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
*/
/* Get current timestamp and count. */
- vblcount = atomic_read(&dev->vblank[crtc].count);
+ vblcount = atomic_read(&dev->_vblank_count[crtc]);
drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ);
/* Compute time difference to timestamp of last vblank */
@@ -1356,14 +1401,14 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
* the timestamp computed above.
*/
smp_mb__before_atomic_inc();
- atomic_inc(&dev->vblank[crtc].count);
+ atomic_inc(&dev->_vblank_count[crtc]);
smp_mb__after_atomic_inc();
} else {
DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
crtc, (int) diff_ns);
}
- DRM_WAKEUP(&dev->vblank[crtc].queue);
+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
drm_handle_vblank_events(dev, crtc);
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index f645268..d752c96 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -86,6 +86,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
if (drm_lock_take(&master->lock, lock->context)) {
master->lock.file_priv = file_priv;
master->lock.lock_time = jiffies;
+ atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
break; /* Got lock */
}
@@ -156,6 +157,8 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
return -EINVAL;
}
+ atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
+
if (drm_lock_free(&master->lock, lock->context)) {
/* FIXME: Should really bail out here. */
}
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 85071a1..fc2adb6 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -707,25 +707,18 @@ EXPORT_SYMBOL(drm_mode_vrefresh);
/**
* drm_mode_set_crtcinfo - set CRTC modesetting parameters
* @p: mode
- * @adjust_flags: a combination of adjustment flags
+ * @adjust_flags: unused? (FIXME)
*
* LOCKING:
* None.
*
* Setup the CRTC modesetting parameters for @p, adjusting if necessary.
- *
- * - The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of
- * interlaced modes.
- * - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for
- * buffers containing two eyes (only adjust the timings when needed, eg. for
- * "frame packing" or "side by side full").
*/
void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
{
if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN))
return;
- p->crtc_clock = p->clock;
p->crtc_hdisplay = p->hdisplay;
p->crtc_hsync_start = p->hsync_start;
p->crtc_hsync_end = p->hsync_end;
@@ -759,20 +752,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
p->crtc_vtotal *= p->vscan;
}
- if (adjust_flags & CRTC_STEREO_DOUBLE) {
- unsigned int layout = p->flags & DRM_MODE_FLAG_3D_MASK;
-
- switch (layout) {
- case DRM_MODE_FLAG_3D_FRAME_PACKING:
- p->crtc_clock *= 2;
- p->crtc_vdisplay += p->crtc_vtotal;
- p->crtc_vsync_start += p->crtc_vtotal;
- p->crtc_vsync_end += p->crtc_vtotal;
- p->crtc_vtotal += p->crtc_vtotal;
- break;
- }
- }
-
p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay);
p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal);
p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay);
@@ -851,16 +830,12 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ
} else if (mode1->clock != mode2->clock)
return false;
- if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) !=
- (mode2->flags & DRM_MODE_FLAG_3D_MASK))
- return false;
-
- return drm_mode_equal_no_clocks_no_stereo(mode1, mode2);
+ return drm_mode_equal_no_clocks(mode1, mode2);
}
EXPORT_SYMBOL(drm_mode_equal);
/**
- * drm_mode_equal_no_clocks_no_stereo - test modes for equality
+ * drm_mode_equal_no_clocks - test modes for equality
* @mode1: first mode
* @mode2: second mode
*
@@ -868,13 +843,12 @@ EXPORT_SYMBOL(drm_mode_equal);
* None.
*
* Check to see if @mode1 and @mode2 are equivalent, but
- * don't check the pixel clocks nor the stereo layout.
+ * don't check the pixel clocks.
*
* RETURNS:
* True if the modes are equal, false otherwise.
*/
-bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
- const struct drm_display_mode *mode2)
+bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)
{
if (mode1->hdisplay == mode2->hdisplay &&
mode1->hsync_start == mode2->hsync_start &&
@@ -886,13 +860,12 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
mode1->vsync_end == mode2->vsync_end &&
mode1->vtotal == mode2->vtotal &&
mode1->vscan == mode2->vscan &&
- (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
- (mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
+ mode1->flags == mode2->flags)
return true;
return false;
}
-EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
+EXPORT_SYMBOL(drm_mode_equal_no_clocks);
/**
* drm_mode_validate_size - make sure modes adhere to size constraints
@@ -1041,7 +1014,7 @@ void drm_mode_connector_list_update(struct drm_connector *connector)
/* if equal delete the probed mode */
mode->status = pmode->status;
/* Merge type bits together */
- mode->type = pmode->type;
+ mode->type |= pmode->type;
list_del(&pmode->head);
drm_mode_destroy(connector->dev, pmode);
break;
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 0267979..1f96cee 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -80,7 +80,7 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali
/* Reserve */
for (addr = (unsigned long)dmah->vaddr, sz = size;
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
- SetPageReserved(virt_to_page((void *)addr));
+ SetPageReserved(virt_to_page(addr));
}
return dmah;
@@ -103,7 +103,7 @@ void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
/* Unreserve */
for (addr = (unsigned long)dmah->vaddr, sz = dmah->size;
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
- ClearPageReserved(virt_to_page((void *)addr));
+ ClearPageReserved(virt_to_page(addr));
}
dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
dmah->busaddr);
@@ -322,36 +322,83 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
DRM_DEBUG("\n");
- dev = drm_dev_alloc(driver, &pdev->dev);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
ret = pci_enable_device(pdev);
if (ret)
- goto err_free;
+ goto err_g1;
dev->pdev = pdev;
+ dev->dev = &pdev->dev;
+
+ dev->pci_device = pdev->device;
+ dev->pci_vendor = pdev->vendor;
+
#ifdef __alpha__
dev->hose = pdev->sysdata;
#endif
- if (drm_core_check_feature(dev, DRIVER_MODESET))
+ mutex_lock(&drm_global_mutex);
+
+ if ((ret = drm_fill_in_dev(dev, ent, driver))) {
+ printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+ goto err_g2;
+ }
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
pci_set_drvdata(pdev, dev);
+ ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+ if (ret)
+ goto err_g2;
+ }
- ret = drm_dev_register(dev, ent->driver_data);
- if (ret)
- goto err_pci;
+ if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
+ ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
+ if (ret)
+ goto err_g21;
+ }
+
+ if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
+ goto err_g3;
+
+ if (dev->driver->load) {
+ ret = dev->driver->load(dev, ent->driver_data);
+ if (ret)
+ goto err_g4;
+ }
+
+ /* setup the grouping for the legacy output */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = drm_mode_group_init_legacy_group(dev,
+ &dev->primary->mode_group);
+ if (ret)
+ goto err_g4;
+ }
+
+ list_add_tail(&dev->driver_item, &driver->device_list);
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
driver->date, pci_name(pdev), dev->primary->index);
+ mutex_unlock(&drm_global_mutex);
return 0;
-err_pci:
+err_g4:
+ drm_put_minor(&dev->primary);
+err_g3:
+ if (dev->render)
+ drm_put_minor(&dev->render);
+err_g21:
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_put_minor(&dev->control);
+err_g2:
pci_disable_device(pdev);
-err_free:
- drm_dev_free(dev);
+err_g1:
+ kfree(dev);
+ mutex_unlock(&drm_global_mutex);
return ret;
}
EXPORT_SYMBOL(drm_get_pci_dev);
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
index fc24fee..f7a18c6 100644
--- a/drivers/gpu/drm/drm_platform.c
+++ b/drivers/gpu/drm/drm_platform.c
@@ -47,15 +47,55 @@ static int drm_get_platform_dev(struct platform_device *platdev,
DRM_DEBUG("\n");
- dev = drm_dev_alloc(driver, &platdev->dev);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->platformdev = platdev;
+ dev->dev = &platdev->dev;
- ret = drm_dev_register(dev, 0);
+ mutex_lock(&drm_global_mutex);
+
+ ret = drm_fill_in_dev(dev, NULL, driver);
+
+ if (ret) {
+ printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+ goto err_g1;
+ }
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+ if (ret)
+ goto err_g1;
+ }
+
+ if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
+ ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
+ if (ret)
+ goto err_g11;
+ }
+
+ ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
if (ret)
- goto err_free;
+ goto err_g2;
+
+ if (dev->driver->load) {
+ ret = dev->driver->load(dev, 0);
+ if (ret)
+ goto err_g3;
+ }
+
+ /* setup the grouping for the legacy output */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = drm_mode_group_init_legacy_group(dev,
+ &dev->primary->mode_group);
+ if (ret)
+ goto err_g3;
+ }
+
+ list_add_tail(&dev->driver_item, &driver->device_list);
+
+ mutex_unlock(&drm_global_mutex);
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -63,8 +103,17 @@ static int drm_get_platform_dev(struct platform_device *platdev,
return 0;
-err_free:
- drm_dev_free(dev);
+err_g3:
+ drm_put_minor(&dev->primary);
+err_g2:
+ if (dev->render)
+ drm_put_minor(&dev->render);
+err_g11:
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_put_minor(&dev->control);
+err_g1:
+ kfree(dev);
+ mutex_unlock(&drm_global_mutex);
return ret;
}
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 56805c3..276d470 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -637,13 +637,14 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
unsigned count;
struct scatterlist *sg;
struct page *page;
- u32 len;
+ u32 len, offset;
int pg_index;
dma_addr_t addr;
pg_index = 0;
for_each_sg(sgt->sgl, sg, sgt->nents, count) {
len = sg->length;
+ offset = sg->offset;
page = sg_page(sg);
addr = sg_dma_address(sg);
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index f53d524..39d8645 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -254,21 +254,81 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
return 0;
}
+int drm_fill_in_dev(struct drm_device *dev,
+ const struct pci_device_id *ent,
+ struct drm_driver *driver)
+{
+ int retcode;
+
+ INIT_LIST_HEAD(&dev->filelist);
+ INIT_LIST_HEAD(&dev->ctxlist);
+ INIT_LIST_HEAD(&dev->vmalist);
+ INIT_LIST_HEAD(&dev->maplist);
+ INIT_LIST_HEAD(&dev->vblank_event_list);
+
+ spin_lock_init(&dev->count_lock);
+ spin_lock_init(&dev->event_lock);
+ mutex_init(&dev->struct_mutex);
+ mutex_init(&dev->ctxlist_mutex);
+
+ if (drm_ht_create(&dev->map_hash, 12)) {
+ return -ENOMEM;
+ }
+
+ /* the DRM has 6 basic counters */
+ dev->counters = 6;
+ dev->types[0] = _DRM_STAT_LOCK;
+ dev->types[1] = _DRM_STAT_OPENS;
+ dev->types[2] = _DRM_STAT_CLOSES;
+ dev->types[3] = _DRM_STAT_IOCTLS;
+ dev->types[4] = _DRM_STAT_LOCKS;
+ dev->types[5] = _DRM_STAT_UNLOCKS;
+
+ dev->driver = driver;
+
+ if (dev->driver->bus->agp_init) {
+ retcode = dev->driver->bus->agp_init(dev);
+ if (retcode)
+ goto error_out_unreg;
+ }
+
+
+
+ retcode = drm_ctxbitmap_init(dev);
+ if (retcode) {
+ DRM_ERROR("Cannot allocate memory for context bitmap.\n");
+ goto error_out_unreg;
+ }
+
+ if (driver->driver_features & DRIVER_GEM) {
+ retcode = drm_gem_init(dev);
+ if (retcode) {
+ DRM_ERROR("Cannot initialize graphics execution "
+ "manager (GEM)\n");
+ goto error_out_unreg;
+ }
+ }
+
+ return 0;
+
+ error_out_unreg:
+ drm_lastclose(dev);
+ return retcode;
+}
+EXPORT_SYMBOL(drm_fill_in_dev);
+
+
/**
- * drm_get_minor - Allocate and register new DRM minor
- * @dev: DRM device
- * @minor: Pointer to where new minor is stored
- * @type: Type of minor
+ * Get a secondary minor number.
*
- * Allocate a new minor of the given type and register it. A pointer to the new
- * minor is returned in @minor.
- * Caller must hold the global DRM mutex.
+ * \param dev device data structure
+ * \param sec-minor structure to hold the assigned minor
+ * \return negative number on failure.
*
- * RETURNS:
- * 0 on success, negative error code on failure.
+ * Search an empty entry and initialize it to the given parameters. This
+ * routines assigns minor numbers to secondary heads of multi-headed cards
*/
-static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
- int type)
+int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
{
struct drm_minor *new_minor;
int ret;
@@ -325,48 +385,37 @@ err_idr:
*minor = NULL;
return ret;
}
+EXPORT_SYMBOL(drm_get_minor);
/**
- * drm_unplug_minor - Unplug DRM minor
- * @minor: Minor to unplug
+ * Put a secondary minor number.
*
- * Unplugs the given DRM minor but keeps the object. So after this returns,
- * minor->dev is still valid so existing open-files can still access it to get
- * device information from their drm_file ojects.
- * If the minor is already unplugged or if @minor is NULL, nothing is done.
- * The global DRM mutex must be held by the caller.
+ * \param sec_minor - structure to be released
+ * \return always zero
*/
-static void drm_unplug_minor(struct drm_minor *minor)
+int drm_put_minor(struct drm_minor **minor_p)
{
- if (!minor || !minor->kdev)
- return;
+ struct drm_minor *minor = *minor_p;
+
+ DRM_DEBUG("release secondary minor %d\n", minor->index);
#if defined(CONFIG_DEBUG_FS)
drm_debugfs_cleanup(minor);
#endif
drm_sysfs_device_remove(minor);
+
idr_remove(&drm_minors_idr, minor->index);
+
+ kfree(minor);
+ *minor_p = NULL;
+ return 0;
}
+EXPORT_SYMBOL(drm_put_minor);
-/**
- * drm_put_minor - Destroy DRM minor
- * @minor: Minor to destroy
- *
- * This calls drm_unplug_minor() on the given minor and then frees it. Nothing
- * is done if @minor is NULL. It is fine to call this on already unplugged
- * minors.
- * The global DRM mutex must be held by the caller.
- */
-static void drm_put_minor(struct drm_minor *minor)
+static void drm_unplug_minor(struct drm_minor *minor)
{
- if (!minor)
- return;
-
- DRM_DEBUG("release secondary minor %d\n", minor->index);
-
- drm_unplug_minor(minor);
- kfree(minor);
+ drm_sysfs_device_remove(minor);
}
/**
@@ -378,237 +427,66 @@ static void drm_put_minor(struct drm_minor *minor)
*/
void drm_put_dev(struct drm_device *dev)
{
+ struct drm_driver *driver;
+ struct drm_map_list *r_list, *list_temp;
+
DRM_DEBUG("\n");
if (!dev) {
DRM_ERROR("cleanup called no dev\n");
return;
}
+ driver = dev->driver;
- drm_dev_unregister(dev);
- drm_dev_free(dev);
-}
-EXPORT_SYMBOL(drm_put_dev);
-
-void drm_unplug_dev(struct drm_device *dev)
-{
- /* for a USB device */
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- drm_unplug_minor(dev->control);
- if (dev->render)
- drm_unplug_minor(dev->render);
- drm_unplug_minor(dev->primary);
-
- mutex_lock(&drm_global_mutex);
-
- drm_device_set_unplugged(dev);
-
- if (dev->open_count == 0) {
- drm_put_dev(dev);
- }
- mutex_unlock(&drm_global_mutex);
-}
-EXPORT_SYMBOL(drm_unplug_dev);
-
-/**
- * drm_dev_alloc - Allocate new drm device
- * @driver: DRM driver to allocate device for
- * @parent: Parent device object
- *
- * Allocate and initialize a new DRM device. No device registration is done.
- * Call drm_dev_register() to advertice the device to user space and register it
- * with other core subsystems.
- *
- * RETURNS:
- * Pointer to new DRM device, or NULL if out of memory.
- */
-struct drm_device *drm_dev_alloc(struct drm_driver *driver,
- struct device *parent)
-{
- struct drm_device *dev;
- int ret;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return NULL;
-
- dev->dev = parent;
- dev->driver = driver;
-
- INIT_LIST_HEAD(&dev->filelist);
- INIT_LIST_HEAD(&dev->ctxlist);
- INIT_LIST_HEAD(&dev->vmalist);
- INIT_LIST_HEAD(&dev->maplist);
- INIT_LIST_HEAD(&dev->vblank_event_list);
-
- spin_lock_init(&dev->count_lock);
- spin_lock_init(&dev->event_lock);
- mutex_init(&dev->struct_mutex);
- mutex_init(&dev->ctxlist_mutex);
+ drm_lastclose(dev);
- if (drm_ht_create(&dev->map_hash, 12))
- goto err_free;
+ if (dev->driver->unload)
+ dev->driver->unload(dev);
- ret = drm_ctxbitmap_init(dev);
- if (ret) {
- DRM_ERROR("Cannot allocate memory for context bitmap.\n");
- goto err_ht;
- }
+ if (dev->driver->bus->agp_destroy)
+ dev->driver->bus->agp_destroy(dev);
- if (driver->driver_features & DRIVER_GEM) {
- ret = drm_gem_init(dev);
- if (ret) {
- DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
- goto err_ctxbitmap;
- }
- }
+ drm_vblank_cleanup(dev);
- return dev;
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+ drm_rmmap(dev, r_list->map);
+ drm_ht_remove(&dev->map_hash);
-err_ctxbitmap:
drm_ctxbitmap_cleanup(dev);
-err_ht:
- drm_ht_remove(&dev->map_hash);
-err_free:
- kfree(dev);
- return NULL;
-}
-EXPORT_SYMBOL(drm_dev_alloc);
-/**
- * drm_dev_free - Free DRM device
- * @dev: DRM device to free
- *
- * Free a DRM device that has previously been allocated via drm_dev_alloc().
- * You must not use kfree() instead or you will leak memory.
- *
- * This must not be called once the device got registered. Use drm_put_dev()
- * instead, which then calls drm_dev_free().
- */
-void drm_dev_free(struct drm_device *dev)
-{
- drm_put_minor(dev->control);
- drm_put_minor(dev->render);
- drm_put_minor(dev->primary);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_put_minor(&dev->control);
- if (dev->driver->driver_features & DRIVER_GEM)
+ if (dev->render)
+ drm_put_minor(&dev->render);
+
+ if (driver->driver_features & DRIVER_GEM)
drm_gem_destroy(dev);
- drm_ctxbitmap_cleanup(dev);
- drm_ht_remove(&dev->map_hash);
+ drm_put_minor(&dev->primary);
+ list_del(&dev->driver_item);
kfree(dev->devname);
kfree(dev);
}
-EXPORT_SYMBOL(drm_dev_free);
+EXPORT_SYMBOL(drm_put_dev);
-/**
- * drm_dev_register - Register DRM device
- * @dev: Device to register
- *
- * Register the DRM device @dev with the system, advertise device to user-space
- * and start normal device operation. @dev must be allocated via drm_dev_alloc()
- * previously.
- *
- * Never call this twice on any device!
- *
- * RETURNS:
- * 0 on success, negative error code on failure.
- */
-int drm_dev_register(struct drm_device *dev, unsigned long flags)
+void drm_unplug_dev(struct drm_device *dev)
{
- int ret;
+ /* for a USB device */
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_unplug_minor(dev->control);
+ if (dev->render)
+ drm_unplug_minor(dev->render);
+ drm_unplug_minor(dev->primary);
mutex_lock(&drm_global_mutex);
- if (dev->driver->bus->agp_init) {
- ret = dev->driver->bus->agp_init(dev);
- if (ret)
- goto out_unlock;
- }
-
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
- if (ret)
- goto err_agp;
- }
-
- if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
- ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
- if (ret)
- goto err_control_node;
- }
-
- ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
- if (ret)
- goto err_render_node;
-
- if (dev->driver->load) {
- ret = dev->driver->load(dev, flags);
- if (ret)
- goto err_primary_node;
- }
+ drm_device_set_unplugged(dev);
- /* setup grouping for legacy outputs */
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- ret = drm_mode_group_init_legacy_group(dev,
- &dev->primary->mode_group);
- if (ret)
- goto err_unload;
+ if (dev->open_count == 0) {
+ drm_put_dev(dev);
}
-
- list_add_tail(&dev->driver_item, &dev->driver->device_list);
-
- ret = 0;
- goto out_unlock;
-
-err_unload:
- if (dev->driver->unload)
- dev->driver->unload(dev);
-err_primary_node:
- drm_put_minor(dev->primary);
-err_render_node:
- drm_put_minor(dev->render);
-err_control_node:
- drm_put_minor(dev->control);
-err_agp:
- if (dev->driver->bus->agp_destroy)
- dev->driver->bus->agp_destroy(dev);
-out_unlock:
mutex_unlock(&drm_global_mutex);
- return ret;
}
-EXPORT_SYMBOL(drm_dev_register);
-
-/**
- * drm_dev_unregister - Unregister DRM device
- * @dev: Device to unregister
- *
- * Unregister the DRM device from the system. This does the reverse of
- * drm_dev_register() but does not deallocate the device. The caller must call
- * drm_dev_free() to free all resources.
- */
-void drm_dev_unregister(struct drm_device *dev)
-{
- struct drm_map_list *r_list, *list_temp;
-
- drm_lastclose(dev);
-
- if (dev->driver->unload)
- dev->driver->unload(dev);
-
- if (dev->driver->bus->agp_destroy)
- dev->driver->bus->agp_destroy(dev);
-
- drm_vblank_cleanup(dev);
-
- list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
- drm_rmmap(dev, r_list->map);
-
- drm_unplug_minor(dev->control);
- drm_unplug_minor(dev->render);
- drm_unplug_minor(dev->primary);
-
- list_del(&dev->driver_item);
-}
-EXPORT_SYMBOL(drm_dev_unregister);
+EXPORT_SYMBOL(drm_unplug_dev);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index c22c309..2290b3b 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -22,8 +22,8 @@
#include <drm/drm_core.h>
#include <drm/drmP.h>
-#define to_drm_minor(d) dev_get_drvdata(d)
-#define to_drm_connector(d) dev_get_drvdata(d)
+#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
+#define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
static struct device_type drm_sysfs_device_minor = {
.name = "drm_minor"
@@ -162,6 +162,20 @@ void drm_sysfs_destroy(void)
drm_class = NULL;
}
+/**
+ * drm_sysfs_device_release - do nothing
+ * @dev: Linux device
+ *
+ * Normally, this would free the DRM device associated with @dev, along
+ * with cleaning up any other stuff. But we do that in the DRM core, so
+ * this function can just return and hope that the core does its job.
+ */
+static void drm_sysfs_device_release(struct device *dev)
+{
+ memset(dev, 0, sizeof(struct device));
+ return;
+}
+
/*
* Connector properties
*/
@@ -366,6 +380,11 @@ static struct bin_attribute edid_attr = {
* properties (so far, connection status, dpms, mode list & edid) and
* generate a hotplug event so userspace knows there's a new connector
* available.
+ *
+ * Note:
+ * This routine should only be called *once* for each registered connector.
+ * A second call for an already registered connector will trigger the BUG_ON
+ * below.
*/
int drm_sysfs_connector_add(struct drm_connector *connector)
{
@@ -375,25 +394,29 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
int i;
int ret;
- if (connector->kdev)
- return 0;
+ /* We shouldn't get called more than once for the same connector */
+ BUG_ON(device_is_registered(&connector->kdev));
+
+ connector->kdev.parent = &dev->primary->kdev;
+ connector->kdev.class = drm_class;
+ connector->kdev.release = drm_sysfs_device_release;
- connector->kdev = device_create(drm_class, dev->primary->kdev,
- 0, connector, "card%d-%s",
- dev->primary->index, drm_get_connector_name(connector));
DRM_DEBUG("adding \"%s\" to sysfs\n",
drm_get_connector_name(connector));
- if (IS_ERR(connector->kdev)) {
- DRM_ERROR("failed to register connector device: %ld\n", PTR_ERR(connector->kdev));
- ret = PTR_ERR(connector->kdev);
+ dev_set_name(&connector->kdev, "card%d-%s",
+ dev->primary->index, drm_get_connector_name(connector));
+ ret = device_register(&connector->kdev);
+
+ if (ret) {
+ DRM_ERROR("failed to register connector device: %d\n", ret);
goto out;
}
/* Standard attributes */
for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) {
- ret = device_create_file(connector->kdev, &connector_attrs[attr_cnt]);
+ ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]);
if (ret)
goto err_out_files;
}
@@ -410,7 +433,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
case DRM_MODE_CONNECTOR_Component:
case DRM_MODE_CONNECTOR_TV:
for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) {
- ret = device_create_file(connector->kdev, &connector_attrs_opt1[opt_cnt]);
+ ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]);
if (ret)
goto err_out_files;
}
@@ -419,7 +442,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
break;
}
- ret = sysfs_create_bin_file(&connector->kdev->kobj, &edid_attr);
+ ret = sysfs_create_bin_file(&connector->kdev.kobj, &edid_attr);
if (ret)
goto err_out_files;
@@ -430,10 +453,10 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
err_out_files:
for (i = 0; i < opt_cnt; i++)
- device_remove_file(connector->kdev, &connector_attrs_opt1[i]);
+ device_remove_file(&connector->kdev, &connector_attrs_opt1[i]);
for (i = 0; i < attr_cnt; i++)
- device_remove_file(connector->kdev, &connector_attrs[i]);
- device_unregister(connector->kdev);
+ device_remove_file(&connector->kdev, &connector_attrs[i]);
+ device_unregister(&connector->kdev);
out:
return ret;
@@ -457,16 +480,16 @@ void drm_sysfs_connector_remove(struct drm_connector *connector)
{
int i;
- if (!connector->kdev)
+ if (!connector->kdev.parent)
return;
DRM_DEBUG("removing \"%s\" from sysfs\n",
drm_get_connector_name(connector));
for (i = 0; i < ARRAY_SIZE(connector_attrs); i++)
- device_remove_file(connector->kdev, &connector_attrs[i]);
- sysfs_remove_bin_file(&connector->kdev->kobj, &edid_attr);
- device_unregister(connector->kdev);
- connector->kdev = NULL;
+ device_remove_file(&connector->kdev, &connector_attrs[i]);
+ sysfs_remove_bin_file(&connector->kdev.kobj, &edid_attr);
+ device_unregister(&connector->kdev);
+ connector->kdev.parent = NULL;
}
EXPORT_SYMBOL(drm_sysfs_connector_remove);
@@ -485,15 +508,10 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
DRM_DEBUG("generating hotplug event\n");
- kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
+ kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
}
EXPORT_SYMBOL(drm_sysfs_hotplug_event);
-static void drm_sysfs_release(struct device *dev)
-{
- kfree(dev);
-}
-
/**
* drm_sysfs_device_add - adds a class device to sysfs for a character driver
* @dev: DRM device to be added
@@ -505,9 +523,15 @@ static void drm_sysfs_release(struct device *dev)
*/
int drm_sysfs_device_add(struct drm_minor *minor)
{
+ int err;
char *minor_str;
- int r;
+ minor->kdev.parent = minor->dev->dev;
+
+ minor->kdev.class = drm_class;
+ minor->kdev.release = drm_sysfs_device_release;
+ minor->kdev.devt = minor->device;
+ minor->kdev.type = &drm_sysfs_device_minor;
if (minor->type == DRM_MINOR_CONTROL)
minor_str = "controlD%d";
else if (minor->type == DRM_MINOR_RENDER)
@@ -515,34 +539,18 @@ int drm_sysfs_device_add(struct drm_minor *minor)
else
minor_str = "card%d";
- minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL);
- if (!minor->kdev) {
- r = -ENOMEM;
- goto error;
- }
+ dev_set_name(&minor->kdev, minor_str, minor->index);
- device_initialize(minor->kdev);
- minor->kdev->devt = MKDEV(DRM_MAJOR, minor->index);
- minor->kdev->class = drm_class;
- minor->kdev->type = &drm_sysfs_device_minor;
- minor->kdev->parent = minor->dev->dev;
- minor->kdev->release = drm_sysfs_release;
- dev_set_drvdata(minor->kdev, minor);
-
- r = dev_set_name(minor->kdev, minor_str, minor->index);
- if (r < 0)
- goto error;
-
- r = device_add(minor->kdev);
- if (r < 0)
- goto error;
+ err = device_register(&minor->kdev);
+ if (err) {
+ DRM_ERROR("device add failed: %d\n", err);
+ goto err_out;
+ }
return 0;
-error:
- DRM_ERROR("device create failed %d\n", r);
- put_device(minor->kdev);
- return r;
+err_out:
+ return err;
}
/**
@@ -554,9 +562,9 @@ error:
*/
void drm_sysfs_device_remove(struct drm_minor *minor)
{
- if (minor->kdev)
- device_unregister(minor->kdev);
- minor->kdev = NULL;
+ if (minor->kdev.parent)
+ device_unregister(&minor->kdev);
+ minor->kdev.parent = NULL;
}
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c
index b179b70..8766472 100644
--- a/drivers/gpu/drm/drm_usb.c
+++ b/drivers/gpu/drm/drm_usb.c
@@ -7,20 +7,57 @@ int drm_get_usb_dev(struct usb_interface *interface,
struct drm_driver *driver)
{
struct drm_device *dev;
+ struct usb_device *usbdev;
int ret;
DRM_DEBUG("\n");
- dev = drm_dev_alloc(driver, &interface->dev);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
- dev->usbdev = interface_to_usbdev(interface);
+ usbdev = interface_to_usbdev(interface);
+ dev->usbdev = usbdev;
+ dev->dev = &interface->dev;
+
+ mutex_lock(&drm_global_mutex);
+
+ ret = drm_fill_in_dev(dev, NULL, driver);
+ if (ret) {
+ printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+ goto err_g1;
+ }
+
usb_set_intfdata(interface, dev);
+ ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+ if (ret)
+ goto err_g1;
+
+ if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
+ ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
+ if (ret)
+ goto err_g11;
+ }
- ret = drm_dev_register(dev, 0);
+ ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
if (ret)
- goto err_free;
+ goto err_g2;
+
+ if (dev->driver->load) {
+ ret = dev->driver->load(dev, 0);
+ if (ret)
+ goto err_g3;
+ }
+
+ /* setup the grouping for the legacy output */
+ ret = drm_mode_group_init_legacy_group(dev,
+ &dev->primary->mode_group);
+ if (ret)
+ goto err_g3;
+
+ list_add_tail(&dev->driver_item, &driver->device_list);
+
+ mutex_unlock(&drm_global_mutex);
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -28,8 +65,16 @@ int drm_get_usb_dev(struct usb_interface *interface,
return 0;
-err_free:
- drm_dev_free(dev);
+err_g3:
+ drm_put_minor(&dev->primary);
+err_g2:
+ if (dev->render)
+ drm_put_minor(&dev->render);
+err_g11:
+ drm_put_minor(&dev->control);
+err_g1:
+ kfree(dev);
+ mutex_unlock(&drm_global_mutex);
return ret;
}
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 93e95d7..b5c5af7 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -301,7 +301,7 @@ static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
- page = virt_to_page((void *)dma->pagelist[page_nr]);
+ page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
get_page(page);
vmf->page = page;
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index f227f54..45b6ef5 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -2,7 +2,6 @@ config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series"
depends on OF && DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 22b8f5e..bb82ef7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -173,37 +173,28 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
static void exynos_drm_preclose(struct drm_device *dev,
struct drm_file *file)
{
- exynos_drm_subdrv_close(dev, file);
-}
-
-static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
-{
struct exynos_drm_private *private = dev->dev_private;
- struct drm_pending_vblank_event *v, *vt;
- struct drm_pending_event *e, *et;
+ struct drm_pending_vblank_event *e, *t;
unsigned long flags;
- if (!file->driver_priv)
- return;
-
- /* Release all events not unhandled by page flip handler. */
+ /* release events of current file */
spin_lock_irqsave(&dev->event_lock, flags);
- list_for_each_entry_safe(v, vt, &private->pageflip_event_list,
+ list_for_each_entry_safe(e, t, &private->pageflip_event_list,
base.link) {
- if (v->base.file_priv == file) {
- list_del(&v->base.link);
- drm_vblank_put(dev, v->pipe);
- v->base.destroy(&v->base);
+ if (e->base.file_priv == file) {
+ list_del(&e->base.link);
+ e->base.destroy(&e->base);
}
}
-
- /* Release all events handled by page flip handler but not freed. */
- list_for_each_entry_safe(e, et, &file->event_list, link) {
- list_del(&e->link);
- e->destroy(e);
- }
spin_unlock_irqrestore(&dev->event_lock, flags);
+ exynos_drm_subdrv_close(dev, file);
+}
+
+static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
+{
+ if (!file->driver_priv)
+ return;
kfree(file->driver_priv);
file->driver_priv = NULL;
@@ -273,6 +264,7 @@ static struct drm_driver exynos_drm_driver = {
.get_vblank_counter = drm_vblank_count,
.enable_vblank = exynos_drm_crtc_enable_vblank,
.disable_vblank = exynos_drm_crtc_disable_vblank,
+ .gem_init_object = exynos_drm_gem_init_object,
.gem_free_object = exynos_drm_gem_free_object,
.gem_vm_ops = &exynos_drm_gem_vm_ops,
.dumb_create = exynos_drm_gem_dumb_create,
@@ -294,11 +286,7 @@ static struct drm_driver exynos_drm_driver = {
static int exynos_drm_platform_probe(struct platform_device *pdev)
{
- int ret;
-
- ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (ret)
- return ret;
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
return drm_platform_init(&exynos_drm_driver, pdev);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index a61878b..868a14d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -31,7 +31,7 @@
#include "exynos_drm_iommu.h"
/*
- * FIMD stands for Fully Interactive Mobile Display and
+ * FIMD is stand for Fully Interactive Mobile Display and
* as a display controller, it transfers contents drawn on memory
* to a LCD Panel through Display Interfaces such as RGB or
* CPU Interface.
@@ -716,20 +716,20 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
{
/*
* enable drm irq mode.
- * - with irq_enabled = true, we can use the vblank feature.
+ * - with irq_enabled = 1, we can use the vblank feature.
*
* P.S. note that we wouldn't use drm irq handler but
* just specific driver own one instead because
* drm framework supports only one irq handler.
*/
- drm_dev->irq_enabled = true;
+ drm_dev->irq_enabled = 1;
/*
- * with vblank_disable_allowed = true, vblank interrupt will be disabled
+ * with vblank_disable_allowed = 1, vblank interrupt will be disabled
* by drm timer once a current process gives up ownership of
* vblank event.(after drm_vblank_put function is called)
*/
- drm_dev->vblank_disable_allowed = true;
+ drm_dev->vblank_disable_allowed = 1;
/* attach this sub driver to iommu mapping if supported. */
if (is_drm_iommu_supported(drm_dev))
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 7bccedc..3271fd4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -383,8 +383,6 @@ out:
g2d_userptr->npages,
g2d_userptr->vma);
- exynos_gem_put_vma(g2d_userptr->vma);
-
if (!g2d_userptr->out_of_list)
list_del_init(&g2d_userptr->list);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 1ade191..49f9cd2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -630,6 +630,11 @@ void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
}
+int exynos_drm_gem_init_object(struct drm_gem_object *obj)
+{
+ return 0;
+}
+
void exynos_drm_gem_free_object(struct drm_gem_object *obj)
{
struct exynos_drm_gem_obj *exynos_gem_obj;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 702ec3a..09555af 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -135,6 +135,9 @@ unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *file_priv);
+/* initialize gem object. */
+int exynos_drm_gem_init_object(struct drm_gem_object *obj);
+
/* free gem object. */
void exynos_drm_gem_free_object(struct drm_gem_object *gem_obj);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index ddaaedd..4400330 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -101,6 +101,7 @@ static struct edid *vidi_get_edid(struct device *dev,
{
struct vidi_context *ctx = get_vidi_context(dev);
struct edid *edid;
+ int edid_len;
/*
* the edid data comes from user side and it would be set
@@ -111,7 +112,8 @@ static struct edid *vidi_get_edid(struct device *dev,
return ERR_PTR(-EFAULT);
}
- edid = drm_edid_duplicate(ctx->raw_edid);
+ edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
+ edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
if (!edid) {
DRM_DEBUG_KMS("failed to allocate edid\n");
return ERR_PTR(-ENOMEM);
@@ -383,20 +385,20 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
{
/*
* enable drm irq mode.
- * - with irq_enabled = true, we can use the vblank feature.
+ * - with irq_enabled = 1, we can use the vblank feature.
*
* P.S. note that we wouldn't use drm irq handler but
* just specific driver own one instead because
* drm framework supports only one irq handler.
*/
- drm_dev->irq_enabled = true;
+ drm_dev->irq_enabled = 1;
/*
- * with vblank_disable_allowed = true, vblank interrupt will be disabled
+ * with vblank_disable_allowed = 1, vblank interrupt will be disabled
* by drm timer once a current process gives up ownership of
* vblank event.(after drm_vblank_put function is called)
*/
- drm_dev->vblank_disable_allowed = true;
+ drm_dev->vblank_disable_allowed = 1;
return 0;
}
@@ -483,6 +485,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
struct exynos_drm_manager *manager;
struct exynos_drm_display_ops *display_ops;
struct drm_exynos_vidi_connection *vidi = data;
+ int edid_len;
if (!vidi) {
DRM_DEBUG_KMS("user data for vidi is null.\n");
@@ -521,7 +524,8 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
DRM_DEBUG_KMS("edid data is invalid.\n");
return -EINVAL;
}
- ctx->raw_edid = drm_edid_duplicate(raw_edid);
+ edid_len = (1 + raw_edid->extensions) * EDID_LENGTH;
+ ctx->raw_edid = kmemdup(raw_edid, edid_len, GFP_KERNEL);
if (!ctx->raw_edid) {
DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
return -ENOMEM;
diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 508cf99..1f6e2df 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -5,7 +5,6 @@ config DRM_GMA500
select FB_CFB_FILLRECT
select FB_CFB_IMAGEBLIT
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_TTM
# GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
select ACPI_VIDEO if ACPI
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 5a9a6a3..162f686 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -634,7 +634,6 @@ const struct psb_ops cdv_chip_ops = {
.crtcs = 2,
.hdmi_mask = (1 << 0) | (1 << 1),
.lvds_mask = (1 << 1),
- .sdvo_mask = (1 << 0),
.cursor_needs_phys = 0,
.sgx_offset = MRST_SGX_OFFSET,
.chip_setup = cdv_chip_setup,
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
index f88a181..f4eb435 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -666,7 +666,7 @@ cdv_intel_dp_i2c_init(struct gma_connector *connector,
strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
intel_dp->adapter.algo_data = &intel_dp->algo;
- intel_dp->adapter.dev.parent = connector->base.kdev;
+ intel_dp->adapter.dev.parent = &connector->base.kdev;
if (is_edp(encoder))
cdv_intel_edp_panel_vdd_on(encoder);
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 94b3fec..01dd7d2 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -714,7 +714,7 @@ static void psb_setup_outputs(struct drm_device *dev)
clone_mask = (1 << INTEL_OUTPUT_ANALOG);
break;
case INTEL_OUTPUT_SDVO:
- crtc_mask = dev_priv->ops->sdvo_mask;
+ crtc_mask = ((1 << 0) | (1 << 1));
clone_mask = (1 << INTEL_OUTPUT_SDVO);
break;
case INTEL_OUTPUT_LVDS:
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index e2db48a..10ae8c5 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -29,6 +29,11 @@
#include <drm/drm_vma_manager.h>
#include "psb_drv.h"
+int psb_gem_init_object(struct drm_gem_object *obj)
+{
+ return -EINVAL;
+}
+
void psb_gem_free_object(struct drm_gem_object *obj)
{
struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c
index 566d330..62cd42e 100644
--- a/drivers/gpu/drm/gma500/intel_gmbus.c
+++ b/drivers/gpu/drm/gma500/intel_gmbus.c
@@ -51,9 +51,6 @@
#define wait_for(COND, MS) _wait_for(COND, MS, 1)
#define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0)
-#define GMBUS_REG_READ(reg) ioread32(dev_priv->gmbus_reg + (reg))
-#define GMBUS_REG_WRITE(reg, val) iowrite32((val), dev_priv->gmbus_reg + (reg))
-
/* Intel GPIO access functions */
#define I2C_RISEFALL_TIME 20
@@ -74,8 +71,7 @@ struct intel_gpio {
void
gma_intel_i2c_reset(struct drm_device *dev)
{
- struct drm_psb_private *dev_priv = dev->dev_private;
- GMBUS_REG_WRITE(GMBUS0, 0);
+ REG_WRITE(GMBUS0, 0);
}
static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable)
@@ -102,10 +98,11 @@ static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable)
static u32 get_reserved(struct intel_gpio *gpio)
{
struct drm_psb_private *dev_priv = gpio->dev_priv;
+ struct drm_device *dev = dev_priv->dev;
u32 reserved = 0;
/* On most chips, these bits must be preserved in software. */
- reserved = GMBUS_REG_READ(gpio->reg) &
+ reserved = REG_READ(gpio->reg) &
(GPIO_DATA_PULLUP_DISABLE |
GPIO_CLOCK_PULLUP_DISABLE);
@@ -116,26 +113,29 @@ static int get_clock(void *data)
{
struct intel_gpio *gpio = data;
struct drm_psb_private *dev_priv = gpio->dev_priv;
+ struct drm_device *dev = dev_priv->dev;
u32 reserved = get_reserved(gpio);
- GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK);
- GMBUS_REG_WRITE(gpio->reg, reserved);
- return (GMBUS_REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0;
+ REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK);
+ REG_WRITE(gpio->reg, reserved);
+ return (REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0;
}
static int get_data(void *data)
{
struct intel_gpio *gpio = data;
struct drm_psb_private *dev_priv = gpio->dev_priv;
+ struct drm_device *dev = dev_priv->dev;
u32 reserved = get_reserved(gpio);
- GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK);
- GMBUS_REG_WRITE(gpio->reg, reserved);
- return (GMBUS_REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0;
+ REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK);
+ REG_WRITE(gpio->reg, reserved);
+ return (REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0;
}
static void set_clock(void *data, int state_high)
{
struct intel_gpio *gpio = data;
struct drm_psb_private *dev_priv = gpio->dev_priv;
+ struct drm_device *dev = dev_priv->dev;
u32 reserved = get_reserved(gpio);
u32 clock_bits;
@@ -145,14 +145,15 @@ static void set_clock(void *data, int state_high)
clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
GPIO_CLOCK_VAL_MASK;
- GMBUS_REG_WRITE(gpio->reg, reserved | clock_bits);
- GMBUS_REG_READ(gpio->reg); /* Posting */
+ REG_WRITE(gpio->reg, reserved | clock_bits);
+ REG_READ(gpio->reg); /* Posting */
}
static void set_data(void *data, int state_high)
{
struct intel_gpio *gpio = data;
struct drm_psb_private *dev_priv = gpio->dev_priv;
+ struct drm_device *dev = dev_priv->dev;
u32 reserved = get_reserved(gpio);
u32 data_bits;
@@ -162,8 +163,8 @@ static void set_data(void *data, int state_high)
data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
GPIO_DATA_VAL_MASK;
- GMBUS_REG_WRITE(gpio->reg, reserved | data_bits);
- GMBUS_REG_READ(gpio->reg);
+ REG_WRITE(gpio->reg, reserved | data_bits);
+ REG_READ(gpio->reg);
}
static struct i2c_adapter *
@@ -250,6 +251,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
struct intel_gmbus,
adapter);
struct drm_psb_private *dev_priv = adapter->algo_data;
+ struct drm_device *dev = dev_priv->dev;
int i, reg_offset;
if (bus->force_bit)
@@ -258,30 +260,28 @@ gmbus_xfer(struct i2c_adapter *adapter,
reg_offset = 0;
- GMBUS_REG_WRITE(GMBUS0 + reg_offset, bus->reg0);
+ REG_WRITE(GMBUS0 + reg_offset, bus->reg0);
for (i = 0; i < num; i++) {
u16 len = msgs[i].len;
u8 *buf = msgs[i].buf;
if (msgs[i].flags & I2C_M_RD) {
- GMBUS_REG_WRITE(GMBUS1 + reg_offset,
- GMBUS_CYCLE_WAIT |
- (i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
- (len << GMBUS_BYTE_COUNT_SHIFT) |
- (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
- GMBUS_SLAVE_READ | GMBUS_SW_RDY);
- GMBUS_REG_READ(GMBUS2+reg_offset);
+ REG_WRITE(GMBUS1 + reg_offset,
+ GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
+ (len << GMBUS_BYTE_COUNT_SHIFT) |
+ (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
+ GMBUS_SLAVE_READ | GMBUS_SW_RDY);
+ REG_READ(GMBUS2+reg_offset);
do {
u32 val, loop = 0;
- if (wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) &
- (GMBUS_SATOER | GMBUS_HW_RDY), 50))
+ if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50))
goto timeout;
- if (GMBUS_REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
+ if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
goto clear_err;
- val = GMBUS_REG_READ(GMBUS3 + reg_offset);
+ val = REG_READ(GMBUS3 + reg_offset);
do {
*buf++ = val & 0xff;
val >>= 8;
@@ -295,20 +295,18 @@ gmbus_xfer(struct i2c_adapter *adapter,
val |= *buf++ << (8 * loop);
} while (--len && ++loop < 4);
- GMBUS_REG_WRITE(GMBUS3 + reg_offset, val);
- GMBUS_REG_WRITE(GMBUS1 + reg_offset,
+ REG_WRITE(GMBUS3 + reg_offset, val);
+ REG_WRITE(GMBUS1 + reg_offset,
(i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) |
(msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) |
(msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
- GMBUS_REG_READ(GMBUS2+reg_offset);
+ REG_READ(GMBUS2+reg_offset);
while (len) {
- if (wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) &
- (GMBUS_SATOER | GMBUS_HW_RDY), 50))
+ if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50))
goto timeout;
- if (GMBUS_REG_READ(GMBUS2 + reg_offset) &
- GMBUS_SATOER)
+ if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
goto clear_err;
val = loop = 0;
@@ -316,14 +314,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
val |= *buf++ << (8 * loop);
} while (--len && ++loop < 4);
- GMBUS_REG_WRITE(GMBUS3 + reg_offset, val);
- GMBUS_REG_READ(GMBUS2+reg_offset);
+ REG_WRITE(GMBUS3 + reg_offset, val);
+ REG_READ(GMBUS2+reg_offset);
}
}
- if (i + 1 < num && wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50))
+ if (i + 1 < num && wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50))
goto timeout;
- if (GMBUS_REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
+ if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
goto clear_err;
}
@@ -334,20 +332,20 @@ clear_err:
* of resetting the GMBUS controller and so clearing the
* BUS_ERROR raised by the slave's NAK.
*/
- GMBUS_REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT);
- GMBUS_REG_WRITE(GMBUS1 + reg_offset, 0);
+ REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT);
+ REG_WRITE(GMBUS1 + reg_offset, 0);
done:
/* Mark the GMBUS interface as disabled. We will re-enable it at the
* start of the next xfer, till then let it sleep.
*/
- GMBUS_REG_WRITE(GMBUS0 + reg_offset, 0);
+ REG_WRITE(GMBUS0 + reg_offset, 0);
return i;
timeout:
DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n",
bus->reg0 & 0xff, bus->adapter.name);
- GMBUS_REG_WRITE(GMBUS0 + reg_offset, 0);
+ REG_WRITE(GMBUS0 + reg_offset, 0);
/* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff);
@@ -401,11 +399,6 @@ int gma_intel_setup_gmbus(struct drm_device *dev)
if (dev_priv->gmbus == NULL)
return -ENOMEM;
- if (IS_MRST(dev))
- dev_priv->gmbus_reg = dev_priv->aux_reg;
- else
- dev_priv->gmbus_reg = dev_priv->vdc_reg;
-
for (i = 0; i < GMBUS_NUM_PORTS; i++) {
struct intel_gmbus *bus = &dev_priv->gmbus[i];
@@ -494,7 +487,6 @@ void gma_intel_teardown_gmbus(struct drm_device *dev)
i2c_del_adapter(&bus->adapter);
}
- dev_priv->gmbus_reg = NULL; /* iounmap is done in driver_unload */
kfree(dev_priv->gmbus);
dev_priv->gmbus = NULL;
}
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
index 5b646c1..45d5af0 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
@@ -39,7 +39,7 @@
#include "psb_intel_reg.h"
#include "mdfld_output.h"
-#include <asm/intel-mid.h>
+#include <asm/mrst.h>
#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c
index 8195e85..54c9896 100644
--- a/drivers/gpu/drm/gma500/oaktrail_crtc.c
+++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c
@@ -26,10 +26,24 @@
#include "gma_display.h"
#include "power.h"
-#define MRST_LIMIT_LVDS_100L 0
-#define MRST_LIMIT_LVDS_83 1
-#define MRST_LIMIT_LVDS_100 2
-#define MRST_LIMIT_SDVO 3
+struct psb_intel_range_t {
+ int min, max;
+};
+
+struct oaktrail_limit_t {
+ struct psb_intel_range_t dot, m, p1;
+};
+
+struct oaktrail_clock_t {
+ /* derived values */
+ int dot;
+ int m;
+ int p1;
+};
+
+#define MRST_LIMIT_LVDS_100L 0
+#define MRST_LIMIT_LVDS_83 1
+#define MRST_LIMIT_LVDS_100 2
#define MRST_DOT_MIN 19750
#define MRST_DOT_MAX 120000
@@ -43,40 +57,21 @@
#define MRST_P1_MAX_0 7
#define MRST_P1_MAX_1 8
-static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
- struct drm_crtc *crtc, int target,
- int refclk, struct gma_clock_t *best_clock);
-
-static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
- struct drm_crtc *crtc, int target,
- int refclk, struct gma_clock_t *best_clock);
-
-static const struct gma_limit_t mrst_limits[] = {
+static const struct oaktrail_limit_t oaktrail_limits[] = {
{ /* MRST_LIMIT_LVDS_100L */
.dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
.m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
.p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
- .find_pll = mrst_lvds_find_best_pll,
},
{ /* MRST_LIMIT_LVDS_83L */
.dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
.m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
.p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
- .find_pll = mrst_lvds_find_best_pll,
},
{ /* MRST_LIMIT_LVDS_100 */
.dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
.m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
.p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
- .find_pll = mrst_lvds_find_best_pll,
- },
- { /* MRST_LIMIT_SDVO */
- .vco = {.min = 1400000, .max = 2800000},
- .n = {.min = 3, .max = 7},
- .m = {.min = 80, .max = 137},
- .p1 = {.min = 1, .max = 2},
- .p2 = {.dot_limit = 200000, .p2_slow = 10, .p2_fast = 10},
- .find_pll = mrst_sdvo_find_best_pll,
},
};
@@ -87,10 +82,9 @@ static const u32 oaktrail_m_converts[] = {
0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
};
-static const struct gma_limit_t *mrst_limit(struct drm_crtc *crtc,
- int refclk)
+static const struct oaktrail_limit_t *oaktrail_limit(struct drm_crtc *crtc)
{
- const struct gma_limit_t *limit = NULL;
+ const struct oaktrail_limit_t *limit = NULL;
struct drm_device *dev = crtc->dev;
struct drm_psb_private *dev_priv = dev->dev_private;
@@ -98,100 +92,45 @@ static const struct gma_limit_t *mrst_limit(struct drm_crtc *crtc,
|| gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
switch (dev_priv->core_freq) {
case 100:
- limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
+ limit = &oaktrail_limits[MRST_LIMIT_LVDS_100L];
break;
case 166:
- limit = &mrst_limits[MRST_LIMIT_LVDS_83];
+ limit = &oaktrail_limits[MRST_LIMIT_LVDS_83];
break;
case 200:
- limit = &mrst_limits[MRST_LIMIT_LVDS_100];
+ limit = &oaktrail_limits[MRST_LIMIT_LVDS_100];
break;
}
- } else if (gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
- limit = &mrst_limits[MRST_LIMIT_SDVO];
} else {
limit = NULL;
- dev_err(dev->dev, "mrst_limit Wrong display type.\n");
+ dev_err(dev->dev, "oaktrail_limit Wrong display type.\n");
}
return limit;
}
/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-static void mrst_lvds_clock(int refclk, struct gma_clock_t *clock)
+static void oaktrail_clock(int refclk, struct oaktrail_clock_t *clock)
{
clock->dot = (refclk * clock->m) / (14 * clock->p1);
}
-static void mrst_print_pll(struct gma_clock_t *clock)
+static void mrstPrintPll(char *prefix, struct oaktrail_clock_t *clock)
{
- DRM_DEBUG_DRIVER("dotclock=%d, m=%d, m1=%d, m2=%d, n=%d, p1=%d, p2=%d\n",
- clock->dot, clock->m, clock->m1, clock->m2, clock->n,
- clock->p1, clock->p2);
-}
-
-static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
- struct drm_crtc *crtc, int target,
- int refclk, struct gma_clock_t *best_clock)
-{
- struct gma_clock_t clock;
- u32 target_vco, actual_freq;
- s32 freq_error, min_error = 100000;
-
- memset(best_clock, 0, sizeof(*best_clock));
-
- for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
- for (clock.n = limit->n.min; clock.n <= limit->n.max;
- clock.n++) {
- for (clock.p1 = limit->p1.min;
- clock.p1 <= limit->p1.max; clock.p1++) {
- /* p2 value always stored in p2_slow on SDVO */
- clock.p = clock.p1 * limit->p2.p2_slow;
- target_vco = target * clock.p;
-
- /* VCO will increase at this point so break */
- if (target_vco > limit->vco.max)
- break;
-
- if (target_vco < limit->vco.min)
- continue;
-
- actual_freq = (refclk * clock.m) /
- (clock.n * clock.p);
- freq_error = 10000 -
- ((target * 10000) / actual_freq);
-
- if (freq_error < -min_error) {
- /* freq_error will start to decrease at
- this point so break */
- break;
- }
-
- if (freq_error < 0)
- freq_error = -freq_error;
-
- if (freq_error < min_error) {
- min_error = freq_error;
- *best_clock = clock;
- }
- }
- }
- if (min_error == 0)
- break;
- }
-
- return min_error == 0;
+ pr_debug("%s: dotclock = %d, m = %d, p1 = %d.\n",
+ prefix, clock->dot, clock->m, clock->p1);
}
/**
* Returns a set of divisors for the desired target clock with the given refclk,
* or FALSE. Divisor values are the actual divisors for
*/
-static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
- struct drm_crtc *crtc, int target,
- int refclk, struct gma_clock_t *best_clock)
+static bool
+mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
+ struct oaktrail_clock_t *best_clock)
{
- struct gma_clock_t clock;
+ struct oaktrail_clock_t clock;
+ const struct oaktrail_limit_t *limit = oaktrail_limit(crtc);
int err = target;
memset(best_clock, 0, sizeof(*best_clock));
@@ -201,7 +140,7 @@ static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
clock.p1++) {
int this_err;
- mrst_lvds_clock(refclk, &clock);
+ oaktrail_clock(refclk, &clock);
this_err = abs(clock.dot - target);
if (this_err < err) {
@@ -210,6 +149,7 @@ static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
}
}
}
+ dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err);
return err != target;
}
@@ -227,10 +167,8 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
int pipe = gma_crtc->pipe;
const struct psb_offset *map = &dev_priv->regmap[pipe];
u32 temp;
- int i;
- int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;
- if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
+ if (pipe == 1) {
oaktrail_crtc_hdmi_dpms(crtc, mode);
return;
}
@@ -245,45 +183,35 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
- for (i = 0; i <= need_aux; i++) {
- /* Enable the DPLL */
- temp = REG_READ_WITH_AUX(map->dpll, i);
- if ((temp & DPLL_VCO_ENABLE) == 0) {
- REG_WRITE_WITH_AUX(map->dpll, temp, i);
- REG_READ_WITH_AUX(map->dpll, i);
- /* Wait for the clocks to stabilize. */
- udelay(150);
- REG_WRITE_WITH_AUX(map->dpll,
- temp | DPLL_VCO_ENABLE, i);
- REG_READ_WITH_AUX(map->dpll, i);
- /* Wait for the clocks to stabilize. */
- udelay(150);
- REG_WRITE_WITH_AUX(map->dpll,
- temp | DPLL_VCO_ENABLE, i);
- REG_READ_WITH_AUX(map->dpll, i);
- /* Wait for the clocks to stabilize. */
- udelay(150);
- }
-
- /* Enable the pipe */
- temp = REG_READ_WITH_AUX(map->conf, i);
- if ((temp & PIPEACONF_ENABLE) == 0) {
- REG_WRITE_WITH_AUX(map->conf,
- temp | PIPEACONF_ENABLE, i);
- }
-
- /* Enable the plane */
- temp = REG_READ_WITH_AUX(map->cntr, i);
- if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
- REG_WRITE_WITH_AUX(map->cntr,
- temp | DISPLAY_PLANE_ENABLE,
- i);
- /* Flush the plane changes */
- REG_WRITE_WITH_AUX(map->base,
- REG_READ_WITH_AUX(map->base, i), i);
- }
-
+ /* Enable the DPLL */
+ temp = REG_READ(map->dpll);
+ if ((temp & DPLL_VCO_ENABLE) == 0) {
+ REG_WRITE(map->dpll, temp);
+ REG_READ(map->dpll);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+ REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE);
+ REG_READ(map->dpll);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+ REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE);
+ REG_READ(map->dpll);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+ }
+ /* Enable the pipe */
+ temp = REG_READ(map->conf);
+ if ((temp & PIPEACONF_ENABLE) == 0)
+ REG_WRITE(map->conf, temp | PIPEACONF_ENABLE);
+ /* Enable the plane */
+ temp = REG_READ(map->cntr);
+ if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
+ REG_WRITE(map->cntr,
+ temp | DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ REG_WRITE(map->base, REG_READ(map->base));
}
+
gma_crtc_load_lut(crtc);
/* Give the overlay scaler a chance to enable
@@ -295,52 +223,48 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
* if it's on this pipe */
/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
- for (i = 0; i <= need_aux; i++) {
- /* Disable the VGA plane that we never use */
- REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
- /* Disable display plane */
- temp = REG_READ_WITH_AUX(map->cntr, i);
- if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
- REG_WRITE_WITH_AUX(map->cntr,
- temp & ~DISPLAY_PLANE_ENABLE, i);
- /* Flush the plane changes */
- REG_WRITE_WITH_AUX(map->base,
- REG_READ(map->base), i);
- REG_READ_WITH_AUX(map->base, i);
- }
+ /* Disable the VGA plane that we never use */
+ REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+ /* Disable display plane */
+ temp = REG_READ(map->cntr);
+ if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+ REG_WRITE(map->cntr,
+ temp & ~DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ REG_WRITE(map->base, REG_READ(map->base));
+ REG_READ(map->base);
+ }
- /* Next, disable display pipes */
- temp = REG_READ_WITH_AUX(map->conf, i);
- if ((temp & PIPEACONF_ENABLE) != 0) {
- REG_WRITE_WITH_AUX(map->conf,
- temp & ~PIPEACONF_ENABLE, i);
- REG_READ_WITH_AUX(map->conf, i);
- }
- /* Wait for for the pipe disable to take effect. */
- gma_wait_for_vblank(dev);
-
- temp = REG_READ_WITH_AUX(map->dpll, i);
- if ((temp & DPLL_VCO_ENABLE) != 0) {
- REG_WRITE_WITH_AUX(map->dpll,
- temp & ~DPLL_VCO_ENABLE, i);
- REG_READ_WITH_AUX(map->dpll, i);
- }
+ /* Next, disable display pipes */
+ temp = REG_READ(map->conf);
+ if ((temp & PIPEACONF_ENABLE) != 0) {
+ REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE);
+ REG_READ(map->conf);
+ }
+ /* Wait for for the pipe disable to take effect. */
+ gma_wait_for_vblank(dev);
- /* Wait for the clocks to turn off. */
- udelay(150);
+ temp = REG_READ(map->dpll);
+ if ((temp & DPLL_VCO_ENABLE) != 0) {
+ REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE);
+ REG_READ(map->dpll);
}
+
+ /* Wait for the clocks to turn off. */
+ udelay(150);
break;
}
- /* Set FIFO Watermarks (values taken from EMGD) */
- REG_WRITE(DSPARB, 0x3f80);
- REG_WRITE(DSPFW1, 0x3f8f0404);
- REG_WRITE(DSPFW2, 0x04040f04);
+ /*Set FIFO Watermarks*/
+ REG_WRITE(DSPARB, 0x3FFF);
+ REG_WRITE(DSPFW1, 0x3F88080A);
+ REG_WRITE(DSPFW2, 0x0b060808);
REG_WRITE(DSPFW3, 0x0);
- REG_WRITE(DSPFW4, 0x04040404);
+ REG_WRITE(DSPFW4, 0x08030404);
REG_WRITE(DSPFW5, 0x04040404);
REG_WRITE(DSPFW6, 0x78);
- REG_WRITE(DSPCHICKENBIT, REG_READ(DSPCHICKENBIT) | 0xc040);
+ REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000);
+ /* Must write Bit 14 of the Chicken Bit Register */
gma_power_end(dev);
}
@@ -373,8 +297,7 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
int pipe = gma_crtc->pipe;
const struct psb_offset *map = &dev_priv->regmap[pipe];
int refclk = 0;
- struct gma_clock_t clock;
- const struct gma_limit_t *limit;
+ struct oaktrail_clock_t clock;
u32 dpll = 0, fp = 0, dspcntr, pipeconf;
bool ok, is_sdvo = false;
bool is_lvds = false;
@@ -383,10 +306,8 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
struct gma_encoder *gma_encoder = NULL;
uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
struct drm_connector *connector;
- int i;
- int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;
- if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
+ if (pipe == 1)
return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
if (!gma_power_begin(dev, true))
@@ -419,17 +340,15 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
}
/* Disable the VGA plane that we never use */
- for (i = 0; i <= need_aux; i++)
- REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
+ REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
/* Disable the panel fitter if it was on our pipe */
if (oaktrail_panel_fitter_pipe(dev) == pipe)
REG_WRITE(PFIT_CONTROL, 0);
- for (i = 0; i <= need_aux; i++) {
- REG_WRITE_WITH_AUX(map->src, ((mode->crtc_hdisplay - 1) << 16) |
- (mode->crtc_vdisplay - 1), i);
- }
+ REG_WRITE(map->src,
+ ((mode->crtc_hdisplay - 1) << 16) |
+ (mode->crtc_vdisplay - 1));
if (gma_encoder)
drm_object_property_get_value(&connector->base,
@@ -446,39 +365,35 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
offsetY = (adjusted_mode->crtc_vdisplay -
mode->crtc_vdisplay) / 2;
- for (i = 0; i <= need_aux; i++) {
- REG_WRITE_WITH_AUX(map->htotal, (mode->crtc_hdisplay - 1) |
- ((adjusted_mode->crtc_htotal - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->vtotal, (mode->crtc_vdisplay - 1) |
- ((adjusted_mode->crtc_vtotal - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->hblank,
- (adjusted_mode->crtc_hblank_start - offsetX - 1) |
- ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->hsync,
- (adjusted_mode->crtc_hsync_start - offsetX - 1) |
- ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->vblank,
- (adjusted_mode->crtc_vblank_start - offsetY - 1) |
- ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->vsync,
- (adjusted_mode->crtc_vsync_start - offsetY - 1) |
- ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16), i);
- }
+ REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) |
+ ((adjusted_mode->crtc_htotal - 1) << 16));
+ REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) |
+ ((adjusted_mode->crtc_vtotal - 1) << 16));
+ REG_WRITE(map->hblank,
+ (adjusted_mode->crtc_hblank_start - offsetX - 1) |
+ ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
+ REG_WRITE(map->hsync,
+ (adjusted_mode->crtc_hsync_start - offsetX - 1) |
+ ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
+ REG_WRITE(map->vblank,
+ (adjusted_mode->crtc_vblank_start - offsetY - 1) |
+ ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
+ REG_WRITE(map->vsync,
+ (adjusted_mode->crtc_vsync_start - offsetY - 1) |
+ ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
} else {
- for (i = 0; i <= need_aux; i++) {
- REG_WRITE_WITH_AUX(map->htotal, (adjusted_mode->crtc_hdisplay - 1) |
- ((adjusted_mode->crtc_htotal - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) |
- ((adjusted_mode->crtc_vtotal - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->hblank, (adjusted_mode->crtc_hblank_start - 1) |
- ((adjusted_mode->crtc_hblank_end - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->hsync, (adjusted_mode->crtc_hsync_start - 1) |
- ((adjusted_mode->crtc_hsync_end - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->vblank, (adjusted_mode->crtc_vblank_start - 1) |
- ((adjusted_mode->crtc_vblank_end - 1) << 16), i);
- REG_WRITE_WITH_AUX(map->vsync, (adjusted_mode->crtc_vsync_start - 1) |
- ((adjusted_mode->crtc_vsync_end - 1) << 16), i);
- }
+ REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) |
+ ((adjusted_mode->crtc_htotal - 1) << 16));
+ REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) |
+ ((adjusted_mode->crtc_vtotal - 1) << 16));
+ REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) |
+ ((adjusted_mode->crtc_hblank_end - 1) << 16));
+ REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) |
+ ((adjusted_mode->crtc_hsync_end - 1) << 16));
+ REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) |
+ ((adjusted_mode->crtc_vblank_end - 1) << 16));
+ REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) |
+ ((adjusted_mode->crtc_vsync_end - 1) << 16));
}
/* Flush the plane changes */
@@ -503,30 +418,21 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
if (is_mipi)
goto oaktrail_crtc_mode_set_exit;
+ refclk = dev_priv->core_freq * 1000;
dpll = 0; /*BIT16 = 0 for 100MHz reference */
- refclk = is_sdvo ? 96000 : dev_priv->core_freq * 1000;
- limit = mrst_limit(crtc, refclk);
- ok = limit->find_pll(limit, crtc, adjusted_mode->clock,
- refclk, &clock);
+ ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);
- if (is_sdvo) {
- /* Convert calculated values to register values */
- clock.p1 = (1L << (clock.p1 - 1));
- clock.m -= 2;
- clock.n = (1L << (clock.n - 1));
+ if (!ok) {
+ dev_dbg(dev->dev, "mrstFindBestPLL fail in oaktrail_crtc_mode_set.\n");
+ } else {
+ dev_dbg(dev->dev, "oaktrail_crtc_mode_set pixel clock = %d,"
+ "m = %x, p1 = %x.\n", clock.dot, clock.m,
+ clock.p1);
}
- if (!ok)
- DRM_ERROR("Failed to find proper PLL settings");
-
- mrst_print_pll(&clock);
-
- if (is_sdvo)
- fp = clock.n << 16 | clock.m;
- else
- fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8;
+ fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8;
dpll |= DPLL_VGA_MODE_DIS;
@@ -550,43 +456,38 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
/* compute bitmask from p1 value */
- if (is_sdvo)
- dpll |= clock.p1 << 16; // dpll |= (1 << (clock.p1 - 1)) << 16;
- else
- dpll |= (1 << (clock.p1 - 2)) << 17;
+ dpll |= (1 << (clock.p1 - 2)) << 17;
dpll |= DPLL_VCO_ENABLE;
+ mrstPrintPll("chosen", &clock);
+
if (dpll & DPLL_VCO_ENABLE) {
- for (i = 0; i <= need_aux; i++) {
- REG_WRITE_WITH_AUX(map->fp0, fp, i);
- REG_WRITE_WITH_AUX(map->dpll, dpll & ~DPLL_VCO_ENABLE, i);
- REG_READ_WITH_AUX(map->dpll, i);
- /* Check the DPLLA lock bit PIPEACONF[29] */
- udelay(150);
- }
+ REG_WRITE(map->fp0, fp);
+ REG_WRITE(map->dpll, dpll & ~DPLL_VCO_ENABLE);
+ REG_READ(map->dpll);
+ /* Check the DPLLA lock bit PIPEACONF[29] */
+ udelay(150);
}
- for (i = 0; i <= need_aux; i++) {
- REG_WRITE_WITH_AUX(map->fp0, fp, i);
- REG_WRITE_WITH_AUX(map->dpll, dpll, i);
- REG_READ_WITH_AUX(map->dpll, i);
- /* Wait for the clocks to stabilize. */
- udelay(150);
+ REG_WRITE(map->fp0, fp);
+ REG_WRITE(map->dpll, dpll);
+ REG_READ(map->dpll);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
- /* write it again -- the BIOS does, after all */
- REG_WRITE_WITH_AUX(map->dpll, dpll, i);
- REG_READ_WITH_AUX(map->dpll, i);
- /* Wait for the clocks to stabilize. */
- udelay(150);
+ /* write it again -- the BIOS does, after all */
+ REG_WRITE(map->dpll, dpll);
+ REG_READ(map->dpll);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
- REG_WRITE_WITH_AUX(map->conf, pipeconf, i);
- REG_READ_WITH_AUX(map->conf, i);
- gma_wait_for_vblank(dev);
+ REG_WRITE(map->conf, pipeconf);
+ REG_READ(map->conf);
+ gma_wait_for_vblank(dev);
- REG_WRITE_WITH_AUX(map->cntr, dspcntr, i);
- gma_wait_for_vblank(dev);
- }
+ REG_WRITE(map->cntr, dspcntr);
+ gma_wait_for_vblank(dev);
oaktrail_crtc_mode_set_exit:
gma_power_end(dev);
@@ -664,9 +565,3 @@ const struct drm_crtc_helper_funcs oaktrail_helper_funcs = {
.commit = gma_crtc_commit,
};
-/* Not used yet */
-const struct gma_clock_funcs mrst_clock_funcs = {
- .clock = mrst_lvds_clock,
- .limit = mrst_limit,
- .pll_is_valid = gma_pll_is_valid,
-};
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
index 368a03a..08747fd 100644
--- a/drivers/gpu/drm/gma500/oaktrail_device.c
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -26,7 +26,7 @@
#include "psb_drv.h"
#include "psb_reg.h"
#include "psb_intel_reg.h"
-#include <asm/intel-mid.h>
+#include <asm/mrst.h>
#include <asm/intel_scu_ipc.h>
#include "mid_bios.h"
#include "intel_bios.h"
@@ -40,9 +40,6 @@ static int oaktrail_output_init(struct drm_device *dev)
dev_err(dev->dev, "DSI is not supported\n");
if (dev_priv->hdmi_priv)
oaktrail_hdmi_init(dev, &dev_priv->mode_dev);
-
- psb_intel_sdvo_init(dev, SDVOB);
-
return 0;
}
@@ -529,7 +526,6 @@ static int oaktrail_chip_setup(struct drm_device *dev)
psb_intel_opregion_init(dev);
psb_intel_init_bios(dev);
}
- gma_intel_setup_gmbus(dev);
oaktrail_hdmi_setup(dev);
return 0;
}
@@ -538,7 +534,6 @@ static void oaktrail_teardown(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- gma_intel_teardown_gmbus(dev);
oaktrail_hdmi_teardown(dev);
if (!dev_priv->has_gct)
psb_intel_destroy_bios(dev);
@@ -551,7 +546,6 @@ const struct psb_ops oaktrail_chip_ops = {
.crtcs = 2,
.hdmi_mask = (1 << 1),
.lvds_mask = (1 << 0),
- .sdvo_mask = (1 << 1),
.cursor_needs_phys = 0,
.sgx_offset = MRST_SGX_OFFSET,
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
index e281070..1eb86c7 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
@@ -99,7 +99,7 @@ static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
i2c_dev->status = I2C_STAT_INIT;
i2c_dev->msg = pmsg;
i2c_dev->buf_offset = 0;
- reinit_completion(&i2c_dev->complete);
+ INIT_COMPLETION(i2c_dev->complete);
/* Enable I2C transaction */
temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION;
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
index 5e06978..e77d721 100644
--- a/drivers/gpu/drm/gma500/oaktrail_lvds.c
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -22,7 +22,7 @@
#include <linux/i2c.h>
#include <drm/drmP.h>
-#include <asm/intel-mid.h>
+#include <asm/mrst.h>
#include "intel_bios.h"
#include "psb_drv.h"
@@ -218,6 +218,30 @@ static const struct drm_encoder_helper_funcs oaktrail_lvds_helper_funcs = {
.commit = oaktrail_lvds_commit,
};
+static struct drm_display_mode lvds_configuration_modes[] = {
+ /* hard coded fixed mode for TPO LTPS LPJ040K001A */
+ { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
+ 846, 1056, 0, 480, 489, 491, 525, 0, 0) },
+ /* hard coded fixed mode for LVDS 800x480 */
+ { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
+ 802, 1024, 0, 480, 481, 482, 525, 0, 0) },
+ /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
+ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
+ 1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
+ /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
+ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
+ 1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
+ /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
+ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
+ 1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
+ /* hard coded fixed mode for LVDS 1024x768 */
+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
+ 1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
+ /* hard coded fixed mode for LVDS 1366x768 */
+ { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
+ 1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
+};
+
/* Returns the panel fixed mode from configuration. */
static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
@@ -279,10 +303,10 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
mode_dev->panel_fixed_mode =
drm_mode_duplicate(dev,
dev_priv->lfp_lvds_vbt_mode);
-
- /* If we still got no mode then bail */
+ /* Then guess */
if (mode_dev->panel_fixed_mode == NULL)
- return;
+ mode_dev->panel_fixed_mode
+ = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
drm_mode_set_name(mode_dev->panel_fixed_mode);
drm_mode_set_crtcinfo(mode_dev->panel_fixed_mode, 0);
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
index 23fb33f..6976786 100644
--- a/drivers/gpu/drm/gma500/psb_device.c
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -373,7 +373,6 @@ const struct psb_ops psb_chip_ops = {
.crtcs = 2,
.hdmi_mask = (1 << 0),
.lvds_mask = (1 << 1),
- .sdvo_mask = (1 << 0),
.cursor_needs_phys = 1,
.sgx_offset = PSB_SGX_OFFSET,
.chip_setup = psb_chip_setup,
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 1199180..fcb4e9f 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -251,12 +251,6 @@ static int psb_driver_unload(struct drm_device *dev)
iounmap(dev_priv->sgx_reg);
dev_priv->sgx_reg = NULL;
}
- if (dev_priv->aux_reg) {
- iounmap(dev_priv->aux_reg);
- dev_priv->aux_reg = NULL;
- }
- if (dev_priv->aux_pdev)
- pci_dev_put(dev_priv->aux_pdev);
/* Destroy VBT data */
psb_intel_destroy_bios(dev);
@@ -272,7 +266,7 @@ static int psb_driver_unload(struct drm_device *dev)
static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
{
struct drm_psb_private *dev_priv;
- unsigned long resource_start, resource_len;
+ unsigned long resource_start;
unsigned long irqflags;
int ret = -ENOMEM;
struct drm_connector *connector;
@@ -302,30 +296,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
if (!dev_priv->sgx_reg)
goto out_err;
- if (IS_MRST(dev)) {
- dev_priv->aux_pdev = pci_get_bus_and_slot(0, PCI_DEVFN(3, 0));
-
- if (dev_priv->aux_pdev) {
- resource_start = pci_resource_start(dev_priv->aux_pdev,
- PSB_AUX_RESOURCE);
- resource_len = pci_resource_len(dev_priv->aux_pdev,
- PSB_AUX_RESOURCE);
- dev_priv->aux_reg = ioremap_nocache(resource_start,
- resource_len);
- if (!dev_priv->aux_reg)
- goto out_err;
-
- DRM_DEBUG_KMS("Found aux vdc");
- } else {
- /* Couldn't find the aux vdc so map to primary vdc */
- dev_priv->aux_reg = dev_priv->vdc_reg;
- DRM_DEBUG_KMS("Couldn't find aux pci device");
- }
- dev_priv->gmbus_reg = dev_priv->aux_reg;
- } else {
- dev_priv->gmbus_reg = dev_priv->vdc_reg;
- }
-
psb_intel_opregion_setup(dev);
ret = dev_priv->ops->chip_setup(dev);
@@ -389,7 +359,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
drm_irq_install(dev);
- dev->vblank_disable_allowed = true;
+ dev->vblank_disable_allowed = 1;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
@@ -479,7 +449,7 @@ static int psb_gamma_ioctl(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
dev_dbg(dev->dev, "Invalid Connector object.\n");
- return -ENOENT;
+ return -EINVAL;
}
connector = obj_to_connector(obj);
@@ -521,7 +491,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, obj_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto mode_op_out;
}
@@ -676,6 +646,7 @@ static struct drm_driver driver = {
.preclose = psb_driver_preclose,
.postclose = psb_driver_close,
+ .gem_init_object = psb_gem_init_object,
.gem_free_object = psb_gem_free_object,
.gem_vm_ops = &psb_gem_vm_ops,
.dumb_create = psb_gem_dumb_create,
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index b59e658..4535ac7 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -44,10 +44,10 @@ enum {
CHIP_MFLD_0130 = 3, /* Medfield */
};
-#define IS_PSB(dev) (((dev)->pdev->device & 0xfffe) == 0x8108)
-#define IS_MRST(dev) (((dev)->pdev->device & 0xfff0) == 0x4100)
-#define IS_MFLD(dev) (((dev)->pdev->device & 0xfff8) == 0x0130)
-#define IS_CDV(dev) (((dev)->pdev->device & 0xfff0) == 0x0be0)
+#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108)
+#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
+#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130)
+#define IS_CDV(dev) (((dev)->pci_device & 0xfff0) == 0x0be0)
/*
* Driver definitions
@@ -75,7 +75,6 @@ enum {
* PCI resource identifiers
*/
#define PSB_MMIO_RESOURCE 0
-#define PSB_AUX_RESOURCE 0
#define PSB_GATT_RESOURCE 2
#define PSB_GTT_RESOURCE 3
/*
@@ -456,7 +455,6 @@ struct psb_ops;
struct drm_psb_private {
struct drm_device *dev;
- struct pci_dev *aux_pdev; /* Currently only used by mrst */
const struct psb_ops *ops;
const struct psb_offset *regmap;
@@ -488,7 +486,6 @@ struct drm_psb_private {
uint8_t __iomem *sgx_reg;
uint8_t __iomem *vdc_reg;
- uint8_t __iomem *aux_reg; /* Auxillary vdc pipe regs */
uint32_t gatt_free_offset;
/*
@@ -535,7 +532,6 @@ struct drm_psb_private {
/* gmbus */
struct intel_gmbus *gmbus;
- uint8_t __iomem *gmbus_reg;
/* Used by SDVO */
int crt_ddc_pin;
@@ -676,7 +672,6 @@ struct psb_ops {
int sgx_offset; /* Base offset of SGX device */
int hdmi_mask; /* Mask of HDMI CRTCs */
int lvds_mask; /* Mask of LVDS CRTCs */
- int sdvo_mask; /* Mask of SDVO CRTCs */
int cursor_needs_phys; /* If cursor base reg need physical address */
/* Sub functions */
@@ -842,6 +837,7 @@ extern const struct drm_connector_helper_funcs
extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
/* gem.c */
+extern int psb_gem_init_object(struct drm_gem_object *obj);
extern void psb_gem_free_object(struct drm_gem_object *obj);
extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
struct drm_file *file);
@@ -932,58 +928,16 @@ static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)
return ioread32(dev_priv->vdc_reg + reg);
}
-static inline uint32_t REGISTER_READ_AUX(struct drm_device *dev, uint32_t reg)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- return ioread32(dev_priv->aux_reg + reg);
-}
-
#define REG_READ(reg) REGISTER_READ(dev, (reg))
-#define REG_READ_AUX(reg) REGISTER_READ_AUX(dev, (reg))
-
-/* Useful for post reads */
-static inline uint32_t REGISTER_READ_WITH_AUX(struct drm_device *dev,
- uint32_t reg, int aux)
-{
- uint32_t val;
-
- if (aux)
- val = REG_READ_AUX(reg);
- else
- val = REG_READ(reg);
-
- return val;
-}
-
-#define REG_READ_WITH_AUX(reg, aux) REGISTER_READ_WITH_AUX(dev, (reg), (aux))
static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
- uint32_t val)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- iowrite32((val), dev_priv->vdc_reg + (reg));
-}
-
-static inline void REGISTER_WRITE_AUX(struct drm_device *dev, uint32_t reg,
uint32_t val)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- iowrite32((val), dev_priv->aux_reg + (reg));
+ iowrite32((val), dev_priv->vdc_reg + (reg));
}
#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val))
-#define REG_WRITE_AUX(reg, val) REGISTER_WRITE_AUX(dev, (reg), (val))
-
-static inline void REGISTER_WRITE_WITH_AUX(struct drm_device *dev, uint32_t reg,
- uint32_t val, int aux)
-{
- if (aux)
- REG_WRITE_AUX(reg, val);
- else
- REG_WRITE(reg, val);
-}
-
-#define REG_WRITE_WITH_AUX(reg, val, aux) REGISTER_WRITE_WITH_AUX(dev, (reg), (val), (aux))
static inline void REGISTER_WRITE16(struct drm_device *dev,
uint32_t reg, uint32_t val)
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
index c8841ac..97f8a03 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -572,7 +572,7 @@ int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
if (!drmmode_obj) {
dev_err(dev->dev, "no such CRTC id\n");
- return -ENOENT;
+ return -EINVAL;
}
crtc = to_gma_crtc(obj_to_crtc(drmmode_obj));
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index 07d3a9e..6f01cdf 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -228,26 +228,24 @@ static void psb_intel_sdvo_write_sdvox(struct psb_intel_sdvo *psb_intel_sdvo, u3
{
struct drm_device *dev = psb_intel_sdvo->base.base.dev;
u32 bval = val, cval = val;
- int i, j;
- int need_aux = IS_MRST(dev) ? 1 : 0;
-
- for (j = 0; j <= need_aux; j++) {
- if (psb_intel_sdvo->sdvo_reg == SDVOB)
- cval = REG_READ_WITH_AUX(SDVOC, j);
- else
- bval = REG_READ_WITH_AUX(SDVOB, j);
+ int i;
- /*
- * Write the registers twice for luck. Sometimes,
- * writing them only once doesn't appear to 'stick'.
- * The BIOS does this too. Yay, magic
- */
- for (i = 0; i < 2; i++) {
- REG_WRITE_WITH_AUX(SDVOB, bval, j);
- REG_READ_WITH_AUX(SDVOB, j);
- REG_WRITE_WITH_AUX(SDVOC, cval, j);
- REG_READ_WITH_AUX(SDVOC, j);
- }
+ if (psb_intel_sdvo->sdvo_reg == SDVOB) {
+ cval = REG_READ(SDVOC);
+ } else {
+ bval = REG_READ(SDVOB);
+ }
+ /*
+ * Write the registers twice for luck. Sometimes,
+ * writing them only once doesn't appear to 'stick'.
+ * The BIOS does this too. Yay, magic
+ */
+ for (i = 0; i < 2; i++)
+ {
+ REG_WRITE(SDVOB, bval);
+ REG_READ(SDVOB);
+ REG_WRITE(SDVOC, cval);
+ REG_READ(SDVOC);
}
}
@@ -997,7 +995,6 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
struct psb_intel_sdvo_dtd input_dtd;
int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode);
int rate;
- int need_aux = IS_MRST(dev) ? 1 : 0;
if (!mode)
return;
@@ -1063,11 +1060,7 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
return;
/* Set the SDVO control regs. */
- if (need_aux)
- sdvox = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
- else
- sdvox = REG_READ(psb_intel_sdvo->sdvo_reg);
-
+ sdvox = REG_READ(psb_intel_sdvo->sdvo_reg);
switch (psb_intel_sdvo->sdvo_reg) {
case SDVOB:
sdvox &= SDVOB_PRESERVE_MASK;
@@ -1097,8 +1090,6 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev;
struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder);
u32 temp;
- int i;
- int need_aux = IS_MRST(dev) ? 1 : 0;
switch (mode) {
case DRM_MODE_DPMS_ON:
@@ -1117,27 +1108,19 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode);
if (mode == DRM_MODE_DPMS_OFF) {
- if (need_aux)
- temp = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
- else
- temp = REG_READ(psb_intel_sdvo->sdvo_reg);
-
+ temp = REG_READ(psb_intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) != 0) {
psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE);
}
}
} else {
bool input1, input2;
+ int i;
u8 status;
- if (need_aux)
- temp = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
- else
- temp = REG_READ(psb_intel_sdvo->sdvo_reg);
-
+ temp = REG_READ(psb_intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0)
psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE);
-
for (i = 0; i < 2; i++)
gma_wait_for_vblank(dev);
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index ba48303..029eccf 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -271,15 +271,15 @@ void psb_irq_preinstall(struct drm_device *dev)
if (gma_power_is_on(dev))
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
- if (dev->vblank[0].enabled)
+ if (dev->vblank_enabled[0])
dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
- if (dev->vblank[1].enabled)
+ if (dev->vblank_enabled[1])
dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
/* FIXME: Handle Medfield irq mask
- if (dev->vblank[1].enabled)
+ if (dev->vblank_enabled[1])
dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
- if (dev->vblank[2].enabled)
+ if (dev->vblank_enabled[2])
dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
*/
@@ -305,17 +305,17 @@ int psb_irq_postinstall(struct drm_device *dev)
PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
- if (dev->vblank[0].enabled)
+ if (dev->vblank_enabled[0])
psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
else
psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
- if (dev->vblank[1].enabled)
+ if (dev->vblank_enabled[1])
psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
else
psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
- if (dev->vblank[2].enabled)
+ if (dev->vblank_enabled[2])
psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
else
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
@@ -339,13 +339,13 @@ void psb_irq_uninstall(struct drm_device *dev)
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
- if (dev->vblank[0].enabled)
+ if (dev->vblank_enabled[0])
psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
- if (dev->vblank[1].enabled)
+ if (dev->vblank_enabled[1])
psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
- if (dev->vblank[2].enabled)
+ if (dev->vblank_enabled[2])
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
@@ -456,7 +456,7 @@ static int psb_vblank_do_wait(struct drm_device *dev,
{
unsigned int cur_vblank;
int ret = 0;
- DRM_WAIT_ON(ret, dev->vblank.queue, 3 * DRM_HZ,
+ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
(((cur_vblank = atomic_read(counter))
- *sequence) <= (1 << 23)));
*sequence = cur_vblank;
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 400b0c4..60e8404 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -17,7 +17,6 @@
-#include <linux/hdmi.h>
#include <linux/module.h>
#include <drm/drmP.h>
@@ -550,8 +549,6 @@ tda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode)
buf[HB(0)] = 0x82;
buf[HB(1)] = 0x02;
buf[HB(2)] = 13;
- buf[PB(1)] = HDMI_SCAN_MODE_UNDERSCAN;
- buf[PB(3)] = HDMI_QUANTIZATION_RANGE_FULL << 2;
buf[PB(4)] = drm_match_cea_mode(mode);
tda998x_write_if(encoder, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf,
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 249fdff..ab1892eb 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -944,6 +944,8 @@ static int i810_dma_vertex(struct drm_device *dev, void *data,
dma->buflist[vertex->idx],
vertex->discard, vertex->used);
+ atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
+ atomic_inc(&dev->counts[_DRM_STAT_DMA]);
sarea_priv->last_enqueue = dev_priv->counter - 1;
sarea_priv->last_dispatch = (int)hw_status[5];
@@ -1103,6 +1105,8 @@ static int i810_dma_mc(struct drm_device *dev, void *data,
i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
mc->last_render);
+ atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
+ atomic_inc(&dev->counts[_DRM_STAT_DMA]);
sarea_priv->last_enqueue = dev_priv->counter - 1;
sarea_priv->last_dispatch = (int)hw_status[5];
@@ -1193,6 +1197,13 @@ static int i810_flip_bufs(struct drm_device *dev, void *data,
int i810_driver_load(struct drm_device *dev, unsigned long flags)
{
+ /* i810 has 4 more counters */
+ dev->counters += 4;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+ dev->types[9] = _DRM_STAT_DMA;
+
pci_set_master(dev->pdev);
return 0;
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
deleted file mode 100644
index 6199d0b..0000000
--- a/drivers/gpu/drm/i915/Kconfig
+++ /dev/null
@@ -1,67 +0,0 @@
-config DRM_I915
- tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics"
- depends on DRM
- depends on AGP
- depends on AGP_INTEL
- # we need shmfs for the swappable backing store, and in particular
- # the shmem_readpage() which depends upon tmpfs
- select SHMEM
- select TMPFS
- select DRM_KMS_HELPER
- # i915 depends on ACPI_VIDEO when ACPI is enabled
- # but for select to work, need to select ACPI_VIDEO's dependencies, ick
- select BACKLIGHT_LCD_SUPPORT if ACPI
- select BACKLIGHT_CLASS_DEVICE if ACPI
- select VIDEO_OUTPUT_CONTROL if ACPI
- select INPUT if ACPI
- select ACPI_VIDEO if ACPI
- select ACPI_BUTTON if ACPI
- help
- Choose this option if you have a system that has "Intel Graphics
- Media Accelerator" or "HD Graphics" integrated graphics,
- including 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G,
- G35, G41, G43, G45 chipsets and Celeron, Pentium, Core i3,
- Core i5, Core i7 as well as Atom CPUs with integrated graphics.
- If M is selected, the module will be called i915. AGP support
- is required for this driver to work. This driver is used by
- the Intel driver in X.org 6.8 and XFree86 4.4 and above. It
- replaces the older i830 module that supported a subset of the
- hardware in older X.org releases.
-
- Note that the older i810/i815 chipsets require the use of the
- i810 driver instead, and the Atom z5xx series has an entirely
- different implementation.
-
-config DRM_I915_KMS
- bool "Enable modesetting on intel by default"
- depends on DRM_I915
- help
- Choose this option if you want kernel modesetting enabled by default,
- and you have a new enough userspace to support this. Running old
- userspaces with this enabled will cause pain. Note that this causes
- the driver to bind to PCI devices, which precludes loading things
- like intelfb.
-
-config DRM_I915_FBDEV
- bool "Enable legacy fbdev support for the modesettting intel driver"
- depends on DRM_I915
- select DRM_KMS_FB_HELPER
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- default y
- help
- Choose this option if you have a need for the legacy fbdev
- support. Note that this support also provide the linux console
- support on top of the intel modesetting driver.
-
-config DRM_I915_PRELIMINARY_HW_SUPPORT
- bool "Enable preliminary support for prerelease Intel hardware by default"
- depends on DRM_I915
- help
- Choose this option if you have prerelease Intel hardware and want the
- i915 driver to support it by default. You can enable such support at
- runtime with the module option i915.preliminary_hw_support=1; this
- option changes the default for that module option.
-
- If in doubt, say "N".
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 41838ea..b8449a8 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -21,9 +21,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
intel_display.o \
intel_crt.o \
intel_lvds.o \
- intel_dsi.o \
- intel_dsi_cmd.o \
- intel_dsi_pll.o \
intel_bios.o \
intel_ddi.o \
intel_dp.o \
@@ -33,6 +30,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
intel_panel.o \
intel_pm.o \
intel_i2c.o \
+ intel_fb.o \
intel_tv.o \
intel_dvo.o \
intel_ringbuffer.o \
@@ -53,8 +51,6 @@ i915-$(CONFIG_COMPAT) += i915_ioc32.o
i915-$(CONFIG_ACPI) += intel_acpi.o
-i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o
-
obj-$(CONFIG_DRM_I915) += i915.o
CFLAGS_i915_trace_points.o := -I$(src)
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h
index 3121633..33a62ad 100644
--- a/drivers/gpu/drm/i915/dvo.h
+++ b/drivers/gpu/drm/i915/dvo.h
@@ -77,6 +77,17 @@ struct intel_dvo_dev_ops {
struct drm_display_mode *mode);
/*
+ * Callback to adjust the mode to be set in the CRTC.
+ *
+ * This allows an output to adjust the clock or even the entire set of
+ * timings, which is used for panels with fixed timings or for
+ * buses with clock limitations.
+ */
+ bool (*mode_fixup)(struct intel_dvo_device *dvo,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+
+ /*
* Callback for preparing mode changes on an output
*/
void (*prepare)(struct intel_dvo_device *dvo);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 6ed45a9..a6f4cb5 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -27,8 +27,6 @@
*/
#include <linux/seq_file.h>
-#include <linux/circ_buf.h>
-#include <linux/ctype.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/export.h>
@@ -40,6 +38,9 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
+#define DRM_I915_RING_DEBUG 1
+
+
#if defined(CONFIG_DEBUG_FS)
enum {
@@ -53,32 +54,6 @@ static const char *yesno(int v)
return v ? "yes" : "no";
}
-/* As the drm_debugfs_init() routines are called before dev->dev_private is
- * allocated we need to hook into the minor for release. */
-static int
-drm_add_fake_info_node(struct drm_minor *minor,
- struct dentry *ent,
- const void *key)
-{
- struct drm_info_node *node;
-
- node = kmalloc(sizeof(*node), GFP_KERNEL);
- if (node == NULL) {
- debugfs_remove(ent);
- return -ENOMEM;
- }
-
- node->minor = minor;
- node->dent = ent;
- node->info_ent = (void *) key;
-
- mutex_lock(&minor->debugfs_lock);
- list_add(&node->list, &minor->debugfs_list);
- mutex_unlock(&minor->debugfs_lock);
-
- return 0;
-}
-
static int i915_capabilities(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -170,13 +145,6 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
seq_printf(m, " (%s)", obj->ring->name);
}
-static void describe_ctx(struct seq_file *m, struct i915_hw_context *ctx)
-{
- seq_putc(m, ctx->is_initialized ? 'I' : 'i');
- seq_putc(m, ctx->remap_slice ? 'R' : 'r');
- seq_putc(m, ' ');
-}
-
static int i915_gem_object_list_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -586,53 +554,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
if (ret)
return ret;
- if (INTEL_INFO(dev)->gen >= 8) {
- int i;
- seq_printf(m, "Master Interrupt Control:\t%08x\n",
- I915_READ(GEN8_MASTER_IRQ));
-
- for (i = 0; i < 4; i++) {
- seq_printf(m, "GT Interrupt IMR %d:\t%08x\n",
- i, I915_READ(GEN8_GT_IMR(i)));
- seq_printf(m, "GT Interrupt IIR %d:\t%08x\n",
- i, I915_READ(GEN8_GT_IIR(i)));
- seq_printf(m, "GT Interrupt IER %d:\t%08x\n",
- i, I915_READ(GEN8_GT_IER(i)));
- }
-
- for_each_pipe(i) {
- seq_printf(m, "Pipe %c IMR:\t%08x\n",
- pipe_name(i),
- I915_READ(GEN8_DE_PIPE_IMR(i)));
- seq_printf(m, "Pipe %c IIR:\t%08x\n",
- pipe_name(i),
- I915_READ(GEN8_DE_PIPE_IIR(i)));
- seq_printf(m, "Pipe %c IER:\t%08x\n",
- pipe_name(i),
- I915_READ(GEN8_DE_PIPE_IER(i)));
- }
-
- seq_printf(m, "Display Engine port interrupt mask:\t%08x\n",
- I915_READ(GEN8_DE_PORT_IMR));
- seq_printf(m, "Display Engine port interrupt identity:\t%08x\n",
- I915_READ(GEN8_DE_PORT_IIR));
- seq_printf(m, "Display Engine port interrupt enable:\t%08x\n",
- I915_READ(GEN8_DE_PORT_IER));
-
- seq_printf(m, "Display Engine misc interrupt mask:\t%08x\n",
- I915_READ(GEN8_DE_MISC_IMR));
- seq_printf(m, "Display Engine misc interrupt identity:\t%08x\n",
- I915_READ(GEN8_DE_MISC_IIR));
- seq_printf(m, "Display Engine misc interrupt enable:\t%08x\n",
- I915_READ(GEN8_DE_MISC_IER));
-
- seq_printf(m, "PCU interrupt mask:\t%08x\n",
- I915_READ(GEN8_PCU_IMR));
- seq_printf(m, "PCU interrupt identity:\t%08x\n",
- I915_READ(GEN8_PCU_IIR));
- seq_printf(m, "PCU interrupt enable:\t%08x\n",
- I915_READ(GEN8_PCU_IER));
- } else if (IS_VALLEYVIEW(dev)) {
+ if (IS_VALLEYVIEW(dev)) {
seq_printf(m, "Display IER:\t%08x\n",
I915_READ(VLV_IER));
seq_printf(m, "Display IIR:\t%08x\n",
@@ -704,7 +626,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
seq_printf(m, "Interrupts received: %d\n",
atomic_read(&dev_priv->irq_received));
for_each_ring(ring, dev_priv, i) {
- if (INTEL_INFO(dev)->gen >= 6) {
+ if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m,
"Graphics Interrupt mask (%s): %08x\n",
ring->name, I915_READ_IMR(ring));
@@ -921,8 +843,6 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
if (IS_GEN5(dev)) {
u16 rgvswctl = I915_READ16(MEMSWCTL);
u16 rgvstat = I915_READ16(MEMSTAT_ILK);
@@ -1401,8 +1321,6 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
return 0;
}
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
if (ret)
return ret;
@@ -1477,12 +1395,12 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- struct intel_fbdev *ifbdev = NULL;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct intel_fbdev *ifbdev;
struct intel_framebuffer *fb;
+ int ret;
-#ifdef CONFIG_DRM_I915_FBDEV
- struct drm_i915_private *dev_priv = dev->dev_private;
- int ret = mutex_lock_interruptible(&dev->mode_config.mutex);
+ ret = mutex_lock_interruptible(&dev->mode_config.mutex);
if (ret)
return ret;
@@ -1498,11 +1416,10 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
describe_obj(m, fb->obj);
seq_putc(m, '\n');
mutex_unlock(&dev->mode_config.mutex);
-#endif
mutex_lock(&dev->mode_config.fb_lock);
list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) {
- if (ifbdev && &fb->base == ifbdev->helper.fb)
+ if (&fb->base == ifbdev->helper.fb)
continue;
seq_printf(m, "user size: %d x %d, depth %d, %d bpp, refcount %d, obj ",
@@ -1525,7 +1442,6 @@ static int i915_context_status(struct seq_file *m, void *unused)
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
- struct i915_hw_context *ctx;
int ret, i;
ret = mutex_lock_interruptible(&dev->mode_config.mutex);
@@ -1544,15 +1460,12 @@ static int i915_context_status(struct seq_file *m, void *unused)
seq_putc(m, '\n');
}
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
- seq_puts(m, "HW context ");
- describe_ctx(m, ctx);
- for_each_ring(ring, dev_priv, i)
- if (ring->default_context == ctx)
- seq_printf(m, "(default context %s) ", ring->name);
-
- describe_obj(m, ctx->obj);
- seq_putc(m, '\n');
+ for_each_ring(ring, dev_priv, i) {
+ if (ring->default_context) {
+ seq_printf(m, "HW default context %s ring ", ring->name);
+ describe_obj(m, ring->default_context->obj);
+ seq_putc(m, '\n');
+ }
}
mutex_unlock(&dev->mode_config.mutex);
@@ -1623,7 +1536,7 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
I915_READ16(C0DRB3));
seq_printf(m, "C1DRB3 = 0x%04x\n",
I915_READ16(C1DRB3));
- } else if (INTEL_INFO(dev)->gen >= 6) {
+ } else if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n",
I915_READ(MAD_DIMM_C0));
seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n",
@@ -1632,12 +1545,8 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
I915_READ(MAD_DIMM_C2));
seq_printf(m, "TILECTL = 0x%08x\n",
I915_READ(TILECTL));
- if (IS_GEN8(dev))
- seq_printf(m, "GAMTARBMODE = 0x%08x\n",
- I915_READ(GAMTARBMODE));
- else
- seq_printf(m, "ARB_MODE = 0x%08x\n",
- I915_READ(ARB_MODE));
+ seq_printf(m, "ARB_MODE = 0x%08x\n",
+ I915_READ(ARB_MODE));
seq_printf(m, "DISP_ARB_CTL = 0x%08x\n",
I915_READ(DISP_ARB_CTL));
}
@@ -1646,37 +1555,18 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
return 0;
}
-static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
+static int i915_ppgtt_info(struct seq_file *m, void *data)
{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
- struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
- int unused, i;
-
- if (!ppgtt)
- return;
-
- seq_printf(m, "Page directories: %d\n", ppgtt->num_pd_pages);
- seq_printf(m, "Page tables: %d\n", ppgtt->num_pt_pages);
- for_each_ring(ring, dev_priv, unused) {
- seq_printf(m, "%s\n", ring->name);
- for (i = 0; i < 4; i++) {
- u32 offset = 0x270 + i * 8;
- u64 pdp = I915_READ(ring->mmio_base + offset + 4);
- pdp <<= 32;
- pdp |= I915_READ(ring->mmio_base + offset);
- for (i = 0; i < 4; i++)
- seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp);
- }
- }
-}
+ int i, ret;
-static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *ring;
- int i;
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
if (INTEL_INFO(dev)->gen == 6)
seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));
@@ -1695,22 +1585,6 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
}
seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
-}
-
-static int i915_ppgtt_info(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_device *dev = node->minor->dev;
-
- int ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
-
- if (INTEL_INFO(dev)->gen >= 8)
- gen8_ppgtt_info(m, dev);
- else if (INTEL_INFO(dev)->gen >= 6)
- gen6_ppgtt_info(m, dev);
-
mutex_unlock(&dev->struct_mutex);
return 0;
@@ -1736,27 +1610,27 @@ static int i915_dpio_info(struct seq_file *m, void *data)
seq_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL));
seq_printf(m, "DPIO_DIV_A: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_DIV_A));
+ vlv_dpio_read(dev_priv, _DPIO_DIV_A));
seq_printf(m, "DPIO_DIV_B: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_DIV_B));
+ vlv_dpio_read(dev_priv, _DPIO_DIV_B));
seq_printf(m, "DPIO_REFSFR_A: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_REFSFR_A));
+ vlv_dpio_read(dev_priv, _DPIO_REFSFR_A));
seq_printf(m, "DPIO_REFSFR_B: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_REFSFR_B));
+ vlv_dpio_read(dev_priv, _DPIO_REFSFR_B));
seq_printf(m, "DPIO_CORE_CLK_A: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_CORE_CLK_A));
+ vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_A));
seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_CORE_CLK_B));
+ vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_B));
seq_printf(m, "DPIO_LPF_COEFF_A: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_LPF_COEFF_A));
+ vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_A));
seq_printf(m, "DPIO_LPF_COEFF_B: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, _DPIO_LPF_COEFF_B));
+ vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_B));
seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n",
- vlv_dpio_read(dev_priv, PIPE_A, DPIO_FASTCLK_DISABLE));
+ vlv_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE));
mutex_unlock(&dev_priv->dpio_lock);
@@ -1781,815 +1655,176 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
struct drm_info_node *node = m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 psrperf = 0;
- bool enabled = false;
-
- seq_printf(m, "Sink_Support: %s\n", yesno(dev_priv->psr.sink_support));
- seq_printf(m, "Source_OK: %s\n", yesno(dev_priv->psr.source_ok));
-
- enabled = HAS_PSR(dev) &&
- I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE;
- seq_printf(m, "Enabled: %s\n", yesno(enabled));
-
- if (HAS_PSR(dev))
- psrperf = I915_READ(EDP_PSR_PERF_CNT(dev)) &
- EDP_PSR_PERF_CNT_MASK;
- seq_printf(m, "Performance_Counter: %u\n", psrperf);
-
- return 0;
-}
-
-static int i915_energy_uJ(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u64 power;
- u32 units;
-
- if (INTEL_INFO(dev)->gen < 6)
- return -ENODEV;
-
- rdmsrl(MSR_RAPL_POWER_UNIT, power);
- power = (power & 0x1f00) >> 8;
- units = 1000000 / (1 << power); /* convert to uJ */
- power = I915_READ(MCH_SECP_NRG_STTS);
- power *= units;
-
- seq_printf(m, "%llu", (long long unsigned)power);
-
- return 0;
-}
-
-static int i915_pc8_status(struct seq_file *m, void *unused)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 psrstat, psrperf;
if (!IS_HASWELL(dev)) {
- seq_puts(m, "not supported\n");
- return 0;
- }
-
- mutex_lock(&dev_priv->pc8.lock);
- seq_printf(m, "Requirements met: %s\n",
- yesno(dev_priv->pc8.requirements_met));
- seq_printf(m, "GPU idle: %s\n", yesno(dev_priv->pc8.gpu_idle));
- seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count);
- seq_printf(m, "IRQs disabled: %s\n",
- yesno(dev_priv->pc8.irqs_disabled));
- seq_printf(m, "Enabled: %s\n", yesno(dev_priv->pc8.enabled));
- mutex_unlock(&dev_priv->pc8.lock);
-
- return 0;
-}
-
-struct pipe_crc_info {
- const char *name;
- struct drm_device *dev;
- enum pipe pipe;
-};
-
-static int i915_pipe_crc_open(struct inode *inode, struct file *filep)
-{
- struct pipe_crc_info *info = inode->i_private;
- struct drm_i915_private *dev_priv = info->dev->dev_private;
- struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
-
- spin_lock_irq(&pipe_crc->lock);
-
- if (pipe_crc->opened) {
- spin_unlock_irq(&pipe_crc->lock);
- return -EBUSY; /* already open */
- }
-
- pipe_crc->opened = true;
- filep->private_data = inode->i_private;
-
- spin_unlock_irq(&pipe_crc->lock);
-
- return 0;
-}
-
-static int i915_pipe_crc_release(struct inode *inode, struct file *filep)
-{
- struct pipe_crc_info *info = inode->i_private;
- struct drm_i915_private *dev_priv = info->dev->dev_private;
- struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
-
- spin_lock_irq(&pipe_crc->lock);
- pipe_crc->opened = false;
- spin_unlock_irq(&pipe_crc->lock);
-
- return 0;
-}
-
-/* (6 fields, 8 chars each, space separated (5) + '\n') */
-#define PIPE_CRC_LINE_LEN (6 * 8 + 5 + 1)
-/* account for \'0' */
-#define PIPE_CRC_BUFFER_LEN (PIPE_CRC_LINE_LEN + 1)
-
-static int pipe_crc_data_count(struct intel_pipe_crc *pipe_crc)
-{
- assert_spin_locked(&pipe_crc->lock);
- return CIRC_CNT(pipe_crc->head, pipe_crc->tail,
- INTEL_PIPE_CRC_ENTRIES_NR);
-}
-
-static ssize_t
-i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,
- loff_t *pos)
-{
- struct pipe_crc_info *info = filep->private_data;
- struct drm_device *dev = info->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
- char buf[PIPE_CRC_BUFFER_LEN];
- int head, tail, n_entries, n;
- ssize_t bytes_read;
-
- /*
- * Don't allow user space to provide buffers not big enough to hold
- * a line of data.
- */
- if (count < PIPE_CRC_LINE_LEN)
- return -EINVAL;
-
- if (pipe_crc->source == INTEL_PIPE_CRC_SOURCE_NONE)
- return 0;
-
- /* nothing to read */
- spin_lock_irq(&pipe_crc->lock);
- while (pipe_crc_data_count(pipe_crc) == 0) {
- int ret;
-
- if (filep->f_flags & O_NONBLOCK) {
- spin_unlock_irq(&pipe_crc->lock);
- return -EAGAIN;
- }
-
- ret = wait_event_interruptible_lock_irq(pipe_crc->wq,
- pipe_crc_data_count(pipe_crc), pipe_crc->lock);
- if (ret) {
- spin_unlock_irq(&pipe_crc->lock);
- return ret;
- }
- }
-
- /* We now have one or more entries to read */
- head = pipe_crc->head;
- tail = pipe_crc->tail;
- n_entries = min((size_t)CIRC_CNT(head, tail, INTEL_PIPE_CRC_ENTRIES_NR),
- count / PIPE_CRC_LINE_LEN);
- spin_unlock_irq(&pipe_crc->lock);
-
- bytes_read = 0;
- n = 0;
- do {
- struct intel_pipe_crc_entry *entry = &pipe_crc->entries[tail];
- int ret;
-
- bytes_read += snprintf(buf, PIPE_CRC_BUFFER_LEN,
- "%8u %8x %8x %8x %8x %8x\n",
- entry->frame, entry->crc[0],
- entry->crc[1], entry->crc[2],
- entry->crc[3], entry->crc[4]);
-
- ret = copy_to_user(user_buf + n * PIPE_CRC_LINE_LEN,
- buf, PIPE_CRC_LINE_LEN);
- if (ret == PIPE_CRC_LINE_LEN)
- return -EFAULT;
-
- BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR);
- tail = (tail + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
- n++;
- } while (--n_entries);
-
- spin_lock_irq(&pipe_crc->lock);
- pipe_crc->tail = tail;
- spin_unlock_irq(&pipe_crc->lock);
-
- return bytes_read;
-}
-
-static const struct file_operations i915_pipe_crc_fops = {
- .owner = THIS_MODULE,
- .open = i915_pipe_crc_open,
- .read = i915_pipe_crc_read,
- .release = i915_pipe_crc_release,
-};
-
-static struct pipe_crc_info i915_pipe_crc_data[I915_MAX_PIPES] = {
- {
- .name = "i915_pipe_A_crc",
- .pipe = PIPE_A,
- },
- {
- .name = "i915_pipe_B_crc",
- .pipe = PIPE_B,
- },
- {
- .name = "i915_pipe_C_crc",
- .pipe = PIPE_C,
- },
-};
-
-static int i915_pipe_crc_create(struct dentry *root, struct drm_minor *minor,
- enum pipe pipe)
-{
- struct drm_device *dev = minor->dev;
- struct dentry *ent;
- struct pipe_crc_info *info = &i915_pipe_crc_data[pipe];
-
- info->dev = dev;
- ent = debugfs_create_file(info->name, S_IRUGO, root, info,
- &i915_pipe_crc_fops);
- if (IS_ERR(ent))
- return PTR_ERR(ent);
-
- return drm_add_fake_info_node(minor, ent, info);
-}
-
-static const char * const pipe_crc_sources[] = {
- "none",
- "plane1",
- "plane2",
- "pf",
- "pipe",
- "TV",
- "DP-B",
- "DP-C",
- "DP-D",
- "auto",
-};
-
-static const char *pipe_crc_source_name(enum intel_pipe_crc_source source)
-{
- BUILD_BUG_ON(ARRAY_SIZE(pipe_crc_sources) != INTEL_PIPE_CRC_SOURCE_MAX);
- return pipe_crc_sources[source];
-}
-
-static int display_crc_ctl_show(struct seq_file *m, void *data)
-{
- struct drm_device *dev = m->private;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
-
- for (i = 0; i < I915_MAX_PIPES; i++)
- seq_printf(m, "%c %s\n", pipe_name(i),
- pipe_crc_source_name(dev_priv->pipe_crc[i].source));
-
- return 0;
-}
-
-static int display_crc_ctl_open(struct inode *inode, struct file *file)
-{
- struct drm_device *dev = inode->i_private;
-
- return single_open(file, display_crc_ctl_show, dev);
-}
-
-static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
- uint32_t *val)
-{
- if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
- *source = INTEL_PIPE_CRC_SOURCE_PIPE;
-
- switch (*source) {
- case INTEL_PIPE_CRC_SOURCE_PIPE:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_INCLUDE_BORDER_I8XX;
- break;
- case INTEL_PIPE_CRC_SOURCE_NONE:
- *val = 0;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe,
- enum intel_pipe_crc_source *source)
-{
- struct intel_encoder *encoder;
- struct intel_crtc *crtc;
- struct intel_digital_port *dig_port;
- int ret = 0;
-
- *source = INTEL_PIPE_CRC_SOURCE_PIPE;
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(encoder, &dev->mode_config.encoder_list,
- base.head) {
- if (!encoder->base.crtc)
- continue;
-
- crtc = to_intel_crtc(encoder->base.crtc);
-
- if (crtc->pipe != pipe)
- continue;
-
- switch (encoder->type) {
- case INTEL_OUTPUT_TVOUT:
- *source = INTEL_PIPE_CRC_SOURCE_TV;
+ seq_puts(m, "PSR not supported on this platform\n");
+ } else if (IS_HASWELL(dev) && I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE) {
+ seq_puts(m, "PSR enabled\n");
+ } else {
+ seq_puts(m, "PSR disabled: ");
+ switch (dev_priv->no_psr_reason) {
+ case PSR_NO_SOURCE:
+ seq_puts(m, "not supported on this platform");
break;
- case INTEL_OUTPUT_DISPLAYPORT:
- case INTEL_OUTPUT_EDP:
- dig_port = enc_to_dig_port(&encoder->base);
- switch (dig_port->port) {
- case PORT_B:
- *source = INTEL_PIPE_CRC_SOURCE_DP_B;
- break;
- case PORT_C:
- *source = INTEL_PIPE_CRC_SOURCE_DP_C;
- break;
- case PORT_D:
- *source = INTEL_PIPE_CRC_SOURCE_DP_D;
- break;
- default:
- WARN(1, "nonexisting DP port %c\n",
- port_name(dig_port->port));
- break;
- }
+ case PSR_NO_SINK:
+ seq_puts(m, "not supported by panel");
+ break;
+ case PSR_MODULE_PARAM:
+ seq_puts(m, "disabled by flag");
+ break;
+ case PSR_CRTC_NOT_ACTIVE:
+ seq_puts(m, "crtc not active");
+ break;
+ case PSR_PWR_WELL_ENABLED:
+ seq_puts(m, "power well enabled");
break;
+ case PSR_NOT_TILED:
+ seq_puts(m, "not tiled");
+ break;
+ case PSR_SPRITE_ENABLED:
+ seq_puts(m, "sprite enabled");
+ break;
+ case PSR_S3D_ENABLED:
+ seq_puts(m, "stereo 3d enabled");
+ break;
+ case PSR_INTERLACED_ENABLED:
+ seq_puts(m, "interlaced enabled");
+ break;
+ case PSR_HSW_NOT_DDIA:
+ seq_puts(m, "HSW ties PSR to DDI A (eDP)");
+ break;
+ default:
+ seq_puts(m, "unknown reason");
}
+ seq_puts(m, "\n");
+ return 0;
}
- mutex_unlock(&dev->mode_config.mutex);
- return ret;
-}
-
-static int vlv_pipe_crc_ctl_reg(struct drm_device *dev,
- enum pipe pipe,
- enum intel_pipe_crc_source *source,
- uint32_t *val)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- bool need_stable_symbols = false;
+ psrstat = I915_READ(EDP_PSR_STATUS_CTL);
- if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
- int ret = i9xx_pipe_crc_auto_source(dev, pipe, source);
- if (ret)
- return ret;
- }
-
- switch (*source) {
- case INTEL_PIPE_CRC_SOURCE_PIPE:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_VLV;
- break;
- case INTEL_PIPE_CRC_SOURCE_DP_B:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV;
- need_stable_symbols = true;
- break;
- case INTEL_PIPE_CRC_SOURCE_DP_C:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV;
- need_stable_symbols = true;
- break;
- case INTEL_PIPE_CRC_SOURCE_NONE:
- *val = 0;
+ seq_puts(m, "PSR Current State: ");
+ switch (psrstat & EDP_PSR_STATUS_STATE_MASK) {
+ case EDP_PSR_STATUS_STATE_IDLE:
+ seq_puts(m, "Reset state\n");
break;
- default:
- return -EINVAL;
- }
-
- /*
- * When the pipe CRC tap point is after the transcoders we need
- * to tweak symbol-level features to produce a deterministic series of
- * symbols for a given frame. We need to reset those features only once
- * a frame (instead of every nth symbol):
- * - DC-balance: used to ensure a better clock recovery from the data
- * link (SDVO)
- * - DisplayPort scrambling: used for EMI reduction
- */
- if (need_stable_symbols) {
- uint32_t tmp = I915_READ(PORT_DFT2_G4X);
-
- WARN_ON(!IS_G4X(dev));
-
- tmp |= DC_BALANCE_RESET_VLV;
- if (pipe == PIPE_A)
- tmp |= PIPE_A_SCRAMBLE_RESET;
- else
- tmp |= PIPE_B_SCRAMBLE_RESET;
-
- I915_WRITE(PORT_DFT2_G4X, tmp);
- }
-
- return 0;
-}
-
-static int i9xx_pipe_crc_ctl_reg(struct drm_device *dev,
- enum pipe pipe,
- enum intel_pipe_crc_source *source,
- uint32_t *val)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- bool need_stable_symbols = false;
-
- if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
- int ret = i9xx_pipe_crc_auto_source(dev, pipe, source);
- if (ret)
- return ret;
- }
-
- switch (*source) {
- case INTEL_PIPE_CRC_SOURCE_PIPE:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX;
+ case EDP_PSR_STATUS_STATE_SRDONACK:
+ seq_puts(m, "Wait for TG/Stream to send on frame of data after SRD conditions are met\n");
break;
- case INTEL_PIPE_CRC_SOURCE_TV:
- if (!SUPPORTS_TV(dev))
- return -EINVAL;
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE;
+ case EDP_PSR_STATUS_STATE_SRDENT:
+ seq_puts(m, "SRD entry\n");
break;
- case INTEL_PIPE_CRC_SOURCE_DP_B:
- if (!IS_G4X(dev))
- return -EINVAL;
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_G4X;
- need_stable_symbols = true;
+ case EDP_PSR_STATUS_STATE_BUFOFF:
+ seq_puts(m, "Wait for buffer turn off\n");
break;
- case INTEL_PIPE_CRC_SOURCE_DP_C:
- if (!IS_G4X(dev))
- return -EINVAL;
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_G4X;
- need_stable_symbols = true;
+ case EDP_PSR_STATUS_STATE_BUFON:
+ seq_puts(m, "Wait for buffer turn on\n");
break;
- case INTEL_PIPE_CRC_SOURCE_DP_D:
- if (!IS_G4X(dev))
- return -EINVAL;
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_G4X;
- need_stable_symbols = true;
+ case EDP_PSR_STATUS_STATE_AUXACK:
+ seq_puts(m, "Wait for AUX to acknowledge on SRD exit\n");
break;
- case INTEL_PIPE_CRC_SOURCE_NONE:
- *val = 0;
+ case EDP_PSR_STATUS_STATE_SRDOFFACK:
+ seq_puts(m, "Wait for TG/Stream to acknowledge the SRD VDM exit\n");
break;
default:
- return -EINVAL;
- }
-
- /*
- * When the pipe CRC tap point is after the transcoders we need
- * to tweak symbol-level features to produce a deterministic series of
- * symbols for a given frame. We need to reset those features only once
- * a frame (instead of every nth symbol):
- * - DC-balance: used to ensure a better clock recovery from the data
- * link (SDVO)
- * - DisplayPort scrambling: used for EMI reduction
- */
- if (need_stable_symbols) {
- uint32_t tmp = I915_READ(PORT_DFT2_G4X);
-
- WARN_ON(!IS_G4X(dev));
-
- I915_WRITE(PORT_DFT_I9XX,
- I915_READ(PORT_DFT_I9XX) | DC_BALANCE_RESET);
-
- if (pipe == PIPE_A)
- tmp |= PIPE_A_SCRAMBLE_RESET;
- else
- tmp |= PIPE_B_SCRAMBLE_RESET;
-
- I915_WRITE(PORT_DFT2_G4X, tmp);
- }
-
- return 0;
-}
-
-static void vlv_undo_pipe_scramble_reset(struct drm_device *dev,
- enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t tmp = I915_READ(PORT_DFT2_G4X);
-
- if (pipe == PIPE_A)
- tmp &= ~PIPE_A_SCRAMBLE_RESET;
- else
- tmp &= ~PIPE_B_SCRAMBLE_RESET;
- if (!(tmp & PIPE_SCRAMBLE_RESET_MASK))
- tmp &= ~DC_BALANCE_RESET_VLV;
- I915_WRITE(PORT_DFT2_G4X, tmp);
-
-}
-
-static void g4x_undo_pipe_scramble_reset(struct drm_device *dev,
- enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t tmp = I915_READ(PORT_DFT2_G4X);
-
- if (pipe == PIPE_A)
- tmp &= ~PIPE_A_SCRAMBLE_RESET;
- else
- tmp &= ~PIPE_B_SCRAMBLE_RESET;
- I915_WRITE(PORT_DFT2_G4X, tmp);
-
- if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) {
- I915_WRITE(PORT_DFT_I9XX,
- I915_READ(PORT_DFT_I9XX) & ~DC_BALANCE_RESET);
- }
-}
-
-static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
- uint32_t *val)
-{
- if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
- *source = INTEL_PIPE_CRC_SOURCE_PIPE;
-
- switch (*source) {
- case INTEL_PIPE_CRC_SOURCE_PLANE1:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_ILK;
- break;
- case INTEL_PIPE_CRC_SOURCE_PLANE2:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_ILK;
- break;
- case INTEL_PIPE_CRC_SOURCE_PIPE:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_ILK;
- break;
- case INTEL_PIPE_CRC_SOURCE_NONE:
- *val = 0;
+ seq_puts(m, "Unknown\n");
break;
- default:
- return -EINVAL;
}
- return 0;
-}
-
-static int ivb_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
- uint32_t *val)
-{
- if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
- *source = INTEL_PIPE_CRC_SOURCE_PF;
-
- switch (*source) {
- case INTEL_PIPE_CRC_SOURCE_PLANE1:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_IVB;
- break;
- case INTEL_PIPE_CRC_SOURCE_PLANE2:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB;
+ seq_puts(m, "Link Status: ");
+ switch (psrstat & EDP_PSR_STATUS_LINK_MASK) {
+ case EDP_PSR_STATUS_LINK_FULL_OFF:
+ seq_puts(m, "Link is fully off\n");
break;
- case INTEL_PIPE_CRC_SOURCE_PF:
- *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB;
+ case EDP_PSR_STATUS_LINK_FULL_ON:
+ seq_puts(m, "Link is fully on\n");
break;
- case INTEL_PIPE_CRC_SOURCE_NONE:
- *val = 0;
+ case EDP_PSR_STATUS_LINK_STANDBY:
+ seq_puts(m, "Link is in standby\n");
break;
default:
- return -EINVAL;
+ seq_puts(m, "Unknown\n");
+ break;
}
- return 0;
-}
-
-static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
- enum intel_pipe_crc_source source)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
- u32 val;
- int ret;
-
- if (pipe_crc->source == source)
- return 0;
-
- /* forbid changing the source without going back to 'none' */
- if (pipe_crc->source && source)
- return -EINVAL;
+ seq_printf(m, "PSR Entry Count: %u\n",
+ psrstat >> EDP_PSR_STATUS_COUNT_SHIFT &
+ EDP_PSR_STATUS_COUNT_MASK);
- if (IS_GEN2(dev))
- ret = i8xx_pipe_crc_ctl_reg(&source, &val);
- else if (INTEL_INFO(dev)->gen < 5)
- ret = i9xx_pipe_crc_ctl_reg(dev, pipe, &source, &val);
- else if (IS_VALLEYVIEW(dev))
- ret = vlv_pipe_crc_ctl_reg(dev,pipe, &source, &val);
- else if (IS_GEN5(dev) || IS_GEN6(dev))
- ret = ilk_pipe_crc_ctl_reg(&source, &val);
- else
- ret = ivb_pipe_crc_ctl_reg(&source, &val);
+ seq_printf(m, "Max Sleep Timer Counter: %u\n",
+ psrstat >> EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT &
+ EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK);
- if (ret != 0)
- return ret;
-
- /* none -> real source transition */
- if (source) {
- DRM_DEBUG_DRIVER("collecting CRCs for pipe %c, %s\n",
- pipe_name(pipe), pipe_crc_source_name(source));
-
- pipe_crc->entries = kzalloc(sizeof(*pipe_crc->entries) *
- INTEL_PIPE_CRC_ENTRIES_NR,
- GFP_KERNEL);
- if (!pipe_crc->entries)
- return -ENOMEM;
-
- spin_lock_irq(&pipe_crc->lock);
- pipe_crc->head = 0;
- pipe_crc->tail = 0;
- spin_unlock_irq(&pipe_crc->lock);
- }
+ seq_printf(m, "Had AUX error: %s\n",
+ yesno(psrstat & EDP_PSR_STATUS_AUX_ERROR));
- pipe_crc->source = source;
+ seq_printf(m, "Sending AUX: %s\n",
+ yesno(psrstat & EDP_PSR_STATUS_AUX_SENDING));
- I915_WRITE(PIPE_CRC_CTL(pipe), val);
- POSTING_READ(PIPE_CRC_CTL(pipe));
+ seq_printf(m, "Sending Idle: %s\n",
+ yesno(psrstat & EDP_PSR_STATUS_SENDING_IDLE));
- /* real source -> none transition */
- if (source == INTEL_PIPE_CRC_SOURCE_NONE) {
- struct intel_pipe_crc_entry *entries;
+ seq_printf(m, "Sending TP2 TP3: %s\n",
+ yesno(psrstat & EDP_PSR_STATUS_SENDING_TP2_TP3));
- DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n",
- pipe_name(pipe));
+ seq_printf(m, "Sending TP1: %s\n",
+ yesno(psrstat & EDP_PSR_STATUS_SENDING_TP1));
- intel_wait_for_vblank(dev, pipe);
+ seq_printf(m, "Idle Count: %u\n",
+ psrstat & EDP_PSR_STATUS_IDLE_MASK);
- spin_lock_irq(&pipe_crc->lock);
- entries = pipe_crc->entries;
- pipe_crc->entries = NULL;
- spin_unlock_irq(&pipe_crc->lock);
-
- kfree(entries);
-
- if (IS_G4X(dev))
- g4x_undo_pipe_scramble_reset(dev, pipe);
- else if (IS_VALLEYVIEW(dev))
- vlv_undo_pipe_scramble_reset(dev, pipe);
- }
+ psrperf = (I915_READ(EDP_PSR_PERF_CNT)) & EDP_PSR_PERF_CNT_MASK;
+ seq_printf(m, "Performance Counter: %u\n", psrperf);
return 0;
}
-/*
- * Parse pipe CRC command strings:
- * command: wsp* object wsp+ name wsp+ source wsp*
- * object: 'pipe'
- * name: (A | B | C)
- * source: (none | plane1 | plane2 | pf)
- * wsp: (#0x20 | #0x9 | #0xA)+
- *
- * eg.:
- * "pipe A plane1" -> Start CRC computations on plane1 of pipe A
- * "pipe A none" -> Stop CRC
- */
-static int display_crc_ctl_tokenize(char *buf, char *words[], int max_words)
-{
- int n_words = 0;
-
- while (*buf) {
- char *end;
-
- /* skip leading white space */
- buf = skip_spaces(buf);
- if (!*buf)
- break; /* end of buffer */
-
- /* find end of word */
- for (end = buf; *end && !isspace(*end); end++)
- ;
-
- if (n_words == max_words) {
- DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
- max_words);
- return -EINVAL; /* ran out of words[] before bytes */
- }
-
- if (*end)
- *end++ = '\0';
- words[n_words++] = buf;
- buf = end;
- }
-
- return n_words;
-}
-
-enum intel_pipe_crc_object {
- PIPE_CRC_OBJECT_PIPE,
-};
-
-static const char * const pipe_crc_objects[] = {
- "pipe",
-};
-
-static int
-display_crc_ctl_parse_object(const char *buf, enum intel_pipe_crc_object *o)
+static int i915_energy_uJ(struct seq_file *m, void *data)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pipe_crc_objects); i++)
- if (!strcmp(buf, pipe_crc_objects[i])) {
- *o = i;
- return 0;
- }
-
- return -EINVAL;
-}
+ struct drm_info_node *node = m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u64 power;
+ u32 units;
-static int display_crc_ctl_parse_pipe(const char *buf, enum pipe *pipe)
-{
- const char name = buf[0];
+ if (INTEL_INFO(dev)->gen < 6)
+ return -ENODEV;
- if (name < 'A' || name >= pipe_name(I915_MAX_PIPES))
- return -EINVAL;
+ rdmsrl(MSR_RAPL_POWER_UNIT, power);
+ power = (power & 0x1f00) >> 8;
+ units = 1000000 / (1 << power); /* convert to uJ */
+ power = I915_READ(MCH_SECP_NRG_STTS);
+ power *= units;
- *pipe = name - 'A';
+ seq_printf(m, "%llu", (long long unsigned)power);
return 0;
}
-static int
-display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pipe_crc_sources); i++)
- if (!strcmp(buf, pipe_crc_sources[i])) {
- *s = i;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int display_crc_ctl_parse(struct drm_device *dev, char *buf, size_t len)
-{
-#define N_WORDS 3
- int n_words;
- char *words[N_WORDS];
- enum pipe pipe;
- enum intel_pipe_crc_object object;
- enum intel_pipe_crc_source source;
-
- n_words = display_crc_ctl_tokenize(buf, words, N_WORDS);
- if (n_words != N_WORDS) {
- DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
- N_WORDS);
- return -EINVAL;
- }
-
- if (display_crc_ctl_parse_object(words[0], &object) < 0) {
- DRM_DEBUG_DRIVER("unknown object %s\n", words[0]);
- return -EINVAL;
- }
-
- if (display_crc_ctl_parse_pipe(words[1], &pipe) < 0) {
- DRM_DEBUG_DRIVER("unknown pipe %s\n", words[1]);
- return -EINVAL;
- }
-
- if (display_crc_ctl_parse_source(words[2], &source) < 0) {
- DRM_DEBUG_DRIVER("unknown source %s\n", words[2]);
- return -EINVAL;
- }
-
- return pipe_crc_set_source(dev, pipe, source);
-}
-
-static ssize_t display_crc_ctl_write(struct file *file, const char __user *ubuf,
- size_t len, loff_t *offp)
+static int i915_pc8_status(struct seq_file *m, void *unused)
{
- struct seq_file *m = file->private_data;
- struct drm_device *dev = m->private;
- char *tmpbuf;
- int ret;
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
- if (len == 0)
+ if (!IS_HASWELL(dev)) {
+ seq_puts(m, "not supported\n");
return 0;
-
- if (len > PAGE_SIZE - 1) {
- DRM_DEBUG_DRIVER("expected <%lu bytes into pipe crc control\n",
- PAGE_SIZE);
- return -E2BIG;
- }
-
- tmpbuf = kmalloc(len + 1, GFP_KERNEL);
- if (!tmpbuf)
- return -ENOMEM;
-
- if (copy_from_user(tmpbuf, ubuf, len)) {
- ret = -EFAULT;
- goto out;
}
- tmpbuf[len] = '\0';
- ret = display_crc_ctl_parse(dev, tmpbuf, len);
-
-out:
- kfree(tmpbuf);
- if (ret < 0)
- return ret;
+ mutex_lock(&dev_priv->pc8.lock);
+ seq_printf(m, "Requirements met: %s\n",
+ yesno(dev_priv->pc8.requirements_met));
+ seq_printf(m, "GPU idle: %s\n", yesno(dev_priv->pc8.gpu_idle));
+ seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count);
+ seq_printf(m, "IRQs disabled: %s\n",
+ yesno(dev_priv->pc8.irqs_disabled));
+ seq_printf(m, "Enabled: %s\n", yesno(dev_priv->pc8.enabled));
+ mutex_unlock(&dev_priv->pc8.lock);
- *offp += len;
- return len;
+ return 0;
}
-static const struct file_operations i915_display_crc_ctl_fops = {
- .owner = THIS_MODULE,
- .open = display_crc_ctl_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = display_crc_ctl_write
-};
-
static int
i915_wedged_get(void *data, u64 *val)
{
@@ -2650,72 +1885,6 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_ring_stop_fops,
i915_ring_stop_get, i915_ring_stop_set,
"0x%08llx\n");
-static int
-i915_ring_missed_irq_get(void *data, u64 *val)
-{
- struct drm_device *dev = data;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- *val = dev_priv->gpu_error.missed_irq_rings;
- return 0;
-}
-
-static int
-i915_ring_missed_irq_set(void *data, u64 val)
-{
- struct drm_device *dev = data;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int ret;
-
- /* Lock against concurrent debugfs callers */
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
- dev_priv->gpu_error.missed_irq_rings = val;
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(i915_ring_missed_irq_fops,
- i915_ring_missed_irq_get, i915_ring_missed_irq_set,
- "0x%08llx\n");
-
-static int
-i915_ring_test_irq_get(void *data, u64 *val)
-{
- struct drm_device *dev = data;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- *val = dev_priv->gpu_error.test_irq_rings;
-
- return 0;
-}
-
-static int
-i915_ring_test_irq_set(void *data, u64 val)
-{
- struct drm_device *dev = data;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int ret;
-
- DRM_DEBUG_DRIVER("Masking interrupts on rings 0x%08llx\n", val);
-
- /* Lock against concurrent debugfs callers */
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
-
- dev_priv->gpu_error.test_irq_rings = val;
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(i915_ring_test_irq_fops,
- i915_ring_test_irq_get, i915_ring_test_irq_set,
- "0x%08llx\n");
-
#define DROP_UNBOUND 0x1
#define DROP_BOUND 0x2
#define DROP_RETIRE 0x4
@@ -2803,8 +1972,6 @@ i915_max_freq_get(void *data, u64 *val)
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
return -ENODEV;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
if (ret)
return ret;
@@ -2829,8 +1996,6 @@ i915_max_freq_set(void *data, u64 val)
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
return -ENODEV;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);
ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
@@ -2869,8 +2034,6 @@ i915_min_freq_get(void *data, u64 *val)
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
return -ENODEV;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
if (ret)
return ret;
@@ -2895,8 +2058,6 @@ i915_min_freq_set(void *data, u64 val)
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
return -ENODEV;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);
ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
@@ -2975,6 +2136,32 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_cache_sharing_fops,
i915_cache_sharing_get, i915_cache_sharing_set,
"%llu\n");
+/* As the drm_debugfs_init() routines are called before dev->dev_private is
+ * allocated we need to hook into the minor for release. */
+static int
+drm_add_fake_info_node(struct drm_minor *minor,
+ struct dentry *ent,
+ const void *key)
+{
+ struct drm_info_node *node;
+
+ node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
+ if (node == NULL) {
+ debugfs_remove(ent);
+ return -ENOMEM;
+ }
+
+ node->minor = minor;
+ node->dent = ent;
+ node->info_ent = (void *) key;
+
+ mutex_lock(&minor->debugfs_lock);
+ list_add(&node->list, &minor->debugfs_list);
+ mutex_unlock(&minor->debugfs_lock);
+
+ return 0;
+}
+
static int i915_forcewake_open(struct inode *inode, struct file *file)
{
struct drm_device *dev = inode->i_private;
@@ -3040,7 +2227,7 @@ static int i915_debugfs_create(struct dentry *root,
return drm_add_fake_info_node(minor, ent, fops);
}
-static const struct drm_info_list i915_debugfs_list[] = {
+static struct drm_info_list i915_debugfs_list[] = {
{"i915_capabilities", i915_capabilities, 0},
{"i915_gem_objects", i915_gem_object_info, 0},
{"i915_gem_gtt", i915_gem_gtt_info, 0},
@@ -3082,7 +2269,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
-static const struct i915_debugfs_files {
+static struct i915_debugfs_files {
const char *name;
const struct file_operations *fops;
} i915_debugfs_files[] = {
@@ -3091,28 +2278,11 @@ static const struct i915_debugfs_files {
{"i915_min_freq", &i915_min_freq_fops},
{"i915_cache_sharing", &i915_cache_sharing_fops},
{"i915_ring_stop", &i915_ring_stop_fops},
- {"i915_ring_missed_irq", &i915_ring_missed_irq_fops},
- {"i915_ring_test_irq", &i915_ring_test_irq_fops},
{"i915_gem_drop_caches", &i915_drop_caches_fops},
{"i915_error_state", &i915_error_state_fops},
{"i915_next_seqno", &i915_next_seqno_fops},
- {"i915_display_crc_ctl", &i915_display_crc_ctl_fops},
};
-void intel_display_crc_init(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
-
- for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) {
- struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[i];
-
- pipe_crc->opened = false;
- spin_lock_init(&pipe_crc->lock);
- init_waitqueue_head(&pipe_crc->wq);
- }
-}
-
int i915_debugfs_init(struct drm_minor *minor)
{
int ret, i;
@@ -3121,12 +2291,6 @@ int i915_debugfs_init(struct drm_minor *minor)
if (ret)
return ret;
- for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) {
- ret = i915_pipe_crc_create(minor->debugfs_root, minor, i);
- if (ret)
- return ret;
- }
-
for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) {
ret = i915_debugfs_create(minor->debugfs_root, minor,
i915_debugfs_files[i].name,
@@ -3146,17 +2310,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
drm_debugfs_remove_files(i915_debugfs_list,
I915_DEBUGFS_ENTRIES, minor);
-
drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops,
1, minor);
-
- for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) {
- struct drm_info_list *info_list =
- (struct drm_info_list *)&i915_pipe_crc_data[i];
-
- drm_debugfs_remove_files(info_list, 1, minor);
- }
-
for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) {
struct drm_info_list *info_list =
(struct drm_info_list *) i915_debugfs_files[i].fops;
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 0cab2d0..d5c784d 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -52,7 +52,7 @@
intel_ring_emit(LP_RING(dev_priv), x)
#define ADVANCE_LP_RING() \
- __intel_ring_advance(LP_RING(dev_priv))
+ intel_ring_advance(LP_RING(dev_priv))
/**
* Lock test for when it's just for synchronization of ring access.
@@ -641,7 +641,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
if (batch->num_cliprects) {
cliprects = kcalloc(batch->num_cliprects,
- sizeof(*cliprects),
+ sizeof(struct drm_clip_rect),
GFP_KERNEL);
if (cliprects == NULL)
return -ENOMEM;
@@ -703,7 +703,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
if (cmdbuf->num_cliprects) {
cliprects = kcalloc(cmdbuf->num_cliprects,
- sizeof(*cliprects), GFP_KERNEL);
+ sizeof(struct drm_clip_rect), GFP_KERNEL);
if (cliprects == NULL) {
ret = -ENOMEM;
goto fail_batch_free;
@@ -931,7 +931,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
value = READ_BREADCRUMB(dev_priv);
break;
case I915_PARAM_CHIPSET_ID:
- value = dev->pdev->device;
+ value = dev->pci_device;
break;
case I915_PARAM_HAS_GEM:
value = 1;
@@ -1311,15 +1311,13 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto cleanup_gem_stolen;
- intel_power_domains_init_hw(dev);
-
/* Important: The output setup functions called by modeset_init need
* working irqs for e.g. gmbus and dp aux transfers. */
intel_modeset_init(dev);
ret = i915_gem_init(dev);
if (ret)
- goto cleanup_power;
+ goto cleanup_irq;
INIT_WORK(&dev_priv->console_resume_work, intel_console_resume);
@@ -1327,11 +1325,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
/* Always safe in the mode setting case. */
/* FIXME: do pre/post-mode set stuff in core KMS code */
- dev->vblank_disable_allowed = true;
- if (INTEL_INFO(dev)->num_pipes == 0) {
- intel_display_power_put(dev, POWER_DOMAIN_VGA);
+ dev->vblank_disable_allowed = 1;
+ if (INTEL_INFO(dev)->num_pipes == 0)
return 0;
- }
ret = intel_fbdev_init(dev);
if (ret)
@@ -1366,8 +1362,7 @@ cleanup_gem:
mutex_unlock(&dev->struct_mutex);
i915_gem_cleanup_aliasing_ppgtt(dev);
drm_mm_takedown(&dev_priv->gtt.base.mm);
-cleanup_power:
- intel_display_power_put(dev, POWER_DOMAIN_VGA);
+cleanup_irq:
drm_irq_uninstall(dev);
cleanup_gem_stolen:
i915_gem_cleanup_stolen(dev);
@@ -1403,7 +1398,6 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
master->driver_priv = NULL;
}
-#ifdef CONFIG_DRM_I915_FBDEV
static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
{
struct apertures_struct *ap;
@@ -1424,11 +1418,6 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
kfree(ap);
}
-#else
-static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
-{
-}
-#endif
static void i915_dump_device_info(struct drm_i915_private *dev_priv)
{
@@ -1470,13 +1459,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
info = (struct intel_device_info *) flags;
/* Refuse to load on gen6+ without kms enabled. */
- if (info->gen >= 6 && !drm_core_check_feature(dev, DRIVER_MODESET)) {
- DRM_INFO("Your hardware requires kernel modesetting (KMS)\n");
- DRM_INFO("See CONFIG_DRM_I915_KMS, nomodeset, and i915.modeset parameters\n");
+ if (info->gen >= 6 && !drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV;
- }
- dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
+ /* i915 has 4 more counters */
+ dev->counters += 4;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+ dev->types[9] = _DRM_STAT_DMA;
+
+ dev_priv = kzalloc(sizeof(drm_i915_private_t), GFP_KERNEL);
if (dev_priv == NULL)
return -ENOMEM;
@@ -1501,8 +1494,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */
INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work);
- intel_display_crc_init(dev);
-
i915_dump_device_info(dev_priv);
/* Not all pre-production machines fall into this category, only the
@@ -1540,14 +1531,19 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
intel_uncore_early_sanitize(dev);
- /* This must be called before any calls to HAS_PCH_* */
- intel_detect_pch(dev);
-
- intel_uncore_init(dev);
+ if (IS_HASWELL(dev) && (I915_READ(HSW_EDRAM_PRESENT) == 1)) {
+ /* The docs do not explain exactly how the calculation can be
+ * made. It is somewhat guessable, but for now, it's always
+ * 128MB.
+ * NB: We can't write IDICR yet because we do not have gt funcs
+ * set up */
+ dev_priv->ellc_size = 128;
+ DRM_INFO("Found %zuMB of eLLC\n", dev_priv->ellc_size);
+ }
ret = i915_gem_gtt_init(dev);
if (ret)
- goto out_regs;
+ goto put_bridge;
if (drm_core_check_feature(dev, DRIVER_MODESET))
i915_kick_out_firmware_fb(dev_priv);
@@ -1576,7 +1572,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
aperture_size);
if (dev_priv->gtt.mappable == NULL) {
ret = -EIO;
- goto out_gtt;
+ goto out_rmmap;
}
dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base,
@@ -1602,9 +1598,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_mtrrfree;
}
+ /* This must be called before any calls to HAS_PCH_* */
+ intel_detect_pch(dev);
+
intel_irq_init(dev);
intel_pm_init(dev);
intel_uncore_sanitize(dev);
+ intel_uncore_init(dev);
/* Try to make sure MCHBAR is enabled before poking at it */
intel_setup_mchbar(dev);
@@ -1640,13 +1640,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
}
if (HAS_POWER_WELL(dev))
- intel_power_domains_init(dev);
+ i915_init_power_well(dev);
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = i915_load_modeset_init(dev);
if (ret < 0) {
DRM_ERROR("failed to init modeset\n");
- goto out_power_well;
+ goto out_gem_unload;
}
} else {
/* Start out suspended in ums mode. */
@@ -1666,10 +1666,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
return 0;
-out_power_well:
- if (HAS_POWER_WELL(dev))
- intel_power_domains_remove(dev);
- drm_vblank_cleanup(dev);
out_gem_unload:
if (dev_priv->mm.inactive_shrinker.scan_objects)
unregister_shrinker(&dev_priv->mm.inactive_shrinker);
@@ -1683,18 +1679,12 @@ out_gem_unload:
out_mtrrfree:
arch_phys_wc_del(dev_priv->gtt.mtrr);
io_mapping_free(dev_priv->gtt.mappable);
-out_gtt:
- list_del(&dev_priv->gtt.base.global_link);
- drm_mm_takedown(&dev_priv->gtt.base.mm);
dev_priv->gtt.base.cleanup(&dev_priv->gtt.base);
-out_regs:
- intel_uncore_fini(dev);
+out_rmmap:
pci_iounmap(dev->pdev, dev_priv->regs);
put_bridge:
pci_dev_put(dev_priv->bridge_dev);
free_priv:
- if (dev_priv->slab)
- kmem_cache_destroy(dev_priv->slab);
kfree(dev_priv);
return ret;
}
@@ -1710,8 +1700,8 @@ int i915_driver_unload(struct drm_device *dev)
/* The i915.ko module is still not prepared to be loaded when
* the power well is not enabled, so just enable it in case
* we're going to unload/reload. */
- intel_display_set_init_power(dev, true);
- intel_power_domains_remove(dev);
+ intel_set_power_well(dev, true);
+ i915_remove_power_well(dev);
}
i915_teardown_sysfs(dev);
@@ -1719,9 +1709,15 @@ int i915_driver_unload(struct drm_device *dev)
if (dev_priv->mm.inactive_shrinker.scan_objects)
unregister_shrinker(&dev_priv->mm.inactive_shrinker);
- ret = i915_gem_suspend(dev);
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gpu_idle(dev);
if (ret)
DRM_ERROR("failed to idle hardware: %d\n", ret);
+ i915_gem_retire_requests(dev);
+ mutex_unlock(&dev->struct_mutex);
+
+ /* Cancel the retire work handler, which should be idle now. */
+ cancel_delayed_work_sync(&dev_priv->mm.retire_work);
io_mapping_free(dev_priv->gtt.mappable);
arch_phys_wc_del(dev_priv->gtt.mtrr);
@@ -1778,8 +1774,8 @@ int i915_driver_unload(struct drm_device *dev)
list_del(&dev_priv->gtt.base.global_link);
WARN_ON(!list_empty(&dev_priv->vm_list));
drm_mm_takedown(&dev_priv->gtt.base.mm);
-
- drm_vblank_cleanup(dev);
+ if (dev_priv->regs != NULL)
+ pci_iounmap(dev->pdev, dev_priv->regs);
intel_teardown_gmbus(dev);
intel_teardown_mchbar(dev);
@@ -1789,10 +1785,6 @@ int i915_driver_unload(struct drm_device *dev)
dev_priv->gtt.base.cleanup(&dev_priv->gtt.base);
- intel_uncore_fini(dev);
- if (dev_priv->regs != NULL)
- pci_iounmap(dev->pdev, dev_priv->regs);
-
if (dev_priv->slab)
kmem_cache_destroy(dev_priv->slab);
@@ -1804,11 +1796,19 @@ int i915_driver_unload(struct drm_device *dev)
int i915_driver_open(struct drm_device *dev, struct drm_file *file)
{
- int ret;
+ struct drm_i915_file_private *file_priv;
- ret = i915_gem_open(dev, file);
- if (ret)
- return ret;
+ DRM_DEBUG_DRIVER("\n");
+ file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+ if (!file_priv)
+ return -ENOMEM;
+
+ file->driver_priv = file_priv;
+
+ spin_lock_init(&file_priv->mm.lock);
+ INIT_LIST_HEAD(&file_priv->mm.request_list);
+
+ idr_init(&file_priv->context_idr);
return 0;
}
@@ -1836,7 +1836,7 @@ void i915_driver_lastclose(struct drm_device * dev)
return;
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- intel_fbdev_restore_mode(dev);
+ intel_fb_restore_mode(dev);
vga_switcheroo_process_delayed_switch();
return;
}
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 2e367a1..2ad2788 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -160,58 +160,49 @@ extern int intel_agp_enabled;
static const struct intel_device_info intel_i830_info = {
.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2,
.has_overlay = 1, .overlay_needs_physical = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_845g_info = {
.gen = 2, .num_pipes = 1,
.has_overlay = 1, .overlay_needs_physical = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i85x_info = {
.gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2,
.cursor_needs_physical = 1,
.has_overlay = 1, .overlay_needs_physical = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i865g_info = {
.gen = 2, .num_pipes = 1,
.has_overlay = 1, .overlay_needs_physical = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i915g_info = {
.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2,
.has_overlay = 1, .overlay_needs_physical = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i915gm_info = {
.gen = 3, .is_mobile = 1, .num_pipes = 2,
.cursor_needs_physical = 1,
.has_overlay = 1, .overlay_needs_physical = 1,
.supports_tv = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i945g_info = {
.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2,
.has_overlay = 1, .overlay_needs_physical = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i945gm_info = {
.gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2,
.has_hotplug = 1, .cursor_needs_physical = 1,
.has_overlay = 1, .overlay_needs_physical = 1,
.supports_tv = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i965g_info = {
.gen = 4, .is_broadwater = 1, .num_pipes = 2,
.has_hotplug = 1,
.has_overlay = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_i965gm_info = {
@@ -219,20 +210,18 @@ static const struct intel_device_info intel_i965gm_info = {
.is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
.has_overlay = 1,
.supports_tv = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_g33_info = {
.gen = 3, .is_g33 = 1, .num_pipes = 2,
.need_gfx_hws = 1, .has_hotplug = 1,
.has_overlay = 1,
- .ring_mask = RENDER_RING,
};
static const struct intel_device_info intel_g45_info = {
.gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2,
.has_pipe_cxsr = 1, .has_hotplug = 1,
- .ring_mask = RENDER_RING | BSD_RING,
+ .has_bsd_ring = 1,
};
static const struct intel_device_info intel_gm45_info = {
@@ -240,7 +229,7 @@ static const struct intel_device_info intel_gm45_info = {
.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
.has_pipe_cxsr = 1, .has_hotplug = 1,
.supports_tv = 1,
- .ring_mask = RENDER_RING | BSD_RING,
+ .has_bsd_ring = 1,
};
static const struct intel_device_info intel_pineview_info = {
@@ -252,36 +241,42 @@ static const struct intel_device_info intel_pineview_info = {
static const struct intel_device_info intel_ironlake_d_info = {
.gen = 5, .num_pipes = 2,
.need_gfx_hws = 1, .has_hotplug = 1,
- .ring_mask = RENDER_RING | BSD_RING,
+ .has_bsd_ring = 1,
};
static const struct intel_device_info intel_ironlake_m_info = {
.gen = 5, .is_mobile = 1, .num_pipes = 2,
.need_gfx_hws = 1, .has_hotplug = 1,
.has_fbc = 1,
- .ring_mask = RENDER_RING | BSD_RING,
+ .has_bsd_ring = 1,
};
static const struct intel_device_info intel_sandybridge_d_info = {
.gen = 6, .num_pipes = 2,
.need_gfx_hws = 1, .has_hotplug = 1,
- .ring_mask = RENDER_RING | BSD_RING | BLT_RING,
+ .has_bsd_ring = 1,
+ .has_blt_ring = 1,
.has_llc = 1,
+ .has_force_wake = 1,
};
static const struct intel_device_info intel_sandybridge_m_info = {
.gen = 6, .is_mobile = 1, .num_pipes = 2,
.need_gfx_hws = 1, .has_hotplug = 1,
.has_fbc = 1,
- .ring_mask = RENDER_RING | BSD_RING | BLT_RING,
+ .has_bsd_ring = 1,
+ .has_blt_ring = 1,
.has_llc = 1,
+ .has_force_wake = 1,
};
#define GEN7_FEATURES \
.gen = 7, .num_pipes = 3, \
.need_gfx_hws = 1, .has_hotplug = 1, \
- .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
- .has_llc = 1
+ .has_bsd_ring = 1, \
+ .has_blt_ring = 1, \
+ .has_llc = 1, \
+ .has_force_wake = 1
static const struct intel_device_info intel_ivybridge_d_info = {
GEN7_FEATURES,
@@ -323,7 +318,7 @@ static const struct intel_device_info intel_haswell_d_info = {
.is_haswell = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
- .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+ .has_vebox_ring = 1,
};
static const struct intel_device_info intel_haswell_m_info = {
@@ -333,25 +328,7 @@ static const struct intel_device_info intel_haswell_m_info = {
.has_ddi = 1,
.has_fpga_dbg = 1,
.has_fbc = 1,
- .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
-};
-
-static const struct intel_device_info intel_broadwell_d_info = {
- .is_preliminary = 1,
- .gen = 8, .num_pipes = 3,
- .need_gfx_hws = 1, .has_hotplug = 1,
- .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
- .has_llc = 1,
- .has_ddi = 1,
-};
-
-static const struct intel_device_info intel_broadwell_m_info = {
- .is_preliminary = 1,
- .gen = 8, .is_mobile = 1, .num_pipes = 3,
- .need_gfx_hws = 1, .has_hotplug = 1,
- .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
- .has_llc = 1,
- .has_ddi = 1,
+ .has_vebox_ring = 1,
};
/*
@@ -385,9 +362,7 @@ static const struct intel_device_info intel_broadwell_m_info = {
INTEL_HSW_D_IDS(&intel_haswell_d_info), \
INTEL_HSW_M_IDS(&intel_haswell_m_info), \
INTEL_VLV_M_IDS(&intel_valleyview_m_info), \
- INTEL_VLV_D_IDS(&intel_valleyview_d_info), \
- INTEL_BDW_M_IDS(&intel_broadwell_m_info), \
- INTEL_BDW_D_IDS(&intel_broadwell_d_info)
+ INTEL_VLV_D_IDS(&intel_valleyview_d_info)
static const struct pci_device_id pciidlist[] = { /* aka */
INTEL_PCI_IDS,
@@ -441,19 +416,13 @@ void intel_detect_pch(struct drm_device *dev)
} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
/* PantherPoint is CPT compatible */
dev_priv->pch_type = PCH_CPT;
- DRM_DEBUG_KMS("Found PantherPoint PCH\n");
+ DRM_DEBUG_KMS("Found PatherPoint PCH\n");
WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_LPT;
DRM_DEBUG_KMS("Found LynxPoint PCH\n");
WARN_ON(!IS_HASWELL(dev));
WARN_ON(IS_ULT(dev));
- } else if (IS_BROADWELL(dev)) {
- dev_priv->pch_type = PCH_LPT;
- dev_priv->pch_id =
- INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
- DRM_DEBUG_KMS("This is Broadwell, assuming "
- "LynxPoint LP PCH\n");
} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_LPT;
DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
@@ -478,12 +447,6 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
if (INTEL_INFO(dev)->gen < 6)
return 0;
- /* Until we get further testing... */
- if (IS_GEN8(dev)) {
- WARN_ON(!i915_preliminary_hw_support);
- return 0;
- }
-
if (i915_semaphores >= 0)
return i915_semaphores;
@@ -509,7 +472,7 @@ static int i915_drm_freeze(struct drm_device *dev)
/* We do a lot of poking in a lot of registers, make sure they work
* properly. */
hsw_disable_package_c8(dev_priv);
- intel_display_set_init_power(dev, true);
+ intel_set_power_well(dev, true);
drm_kms_helper_poll_disable(dev);
@@ -519,7 +482,9 @@ static int i915_drm_freeze(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
int error;
- error = i915_gem_suspend(dev);
+ mutex_lock(&dev->struct_mutex);
+ error = i915_gem_idle(dev);
+ mutex_unlock(&dev->struct_mutex);
if (error) {
dev_err(&dev->pdev->dev,
"GEM idle failed, resume might fail\n");
@@ -534,10 +499,8 @@ static int i915_drm_freeze(struct drm_device *dev)
* Disable CRTCs directly since we want to preserve sw state
* for _thaw.
*/
- mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
dev_priv->display.crtc_disable(crtc);
- mutex_unlock(&dev->mode_config.mutex);
intel_modeset_suspend_hw(dev);
}
@@ -615,24 +578,11 @@ static void intel_resume_hotplug(struct drm_device *dev)
drm_helper_hpd_irq_event(dev);
}
-static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
+static int __i915_drm_thaw(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int error = 0;
- intel_uncore_early_sanitize(dev);
-
- intel_uncore_sanitize(dev);
-
- if (drm_core_check_feature(dev, DRIVER_MODESET) &&
- restore_gtt_mappings) {
- mutex_lock(&dev->struct_mutex);
- i915_gem_restore_gtt_mappings(dev);
- mutex_unlock(&dev->struct_mutex);
- }
-
- intel_power_domains_init_hw(dev);
-
i915_restore_state(dev);
intel_opregion_setup(dev);
@@ -692,10 +642,20 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
static int i915_drm_thaw(struct drm_device *dev)
{
- if (drm_core_check_feature(dev, DRIVER_MODESET))
+ int error = 0;
+
+ intel_uncore_sanitize(dev);
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_restore_gtt_mappings(dev);
+ mutex_unlock(&dev->struct_mutex);
+ } else if (drm_core_check_feature(dev, DRIVER_MODESET))
i915_check_and_clear_faults(dev);
- return __i915_drm_thaw(dev, true);
+ __i915_drm_thaw(dev);
+
+ return error;
}
int i915_resume(struct drm_device *dev)
@@ -711,12 +671,20 @@ int i915_resume(struct drm_device *dev)
pci_set_master(dev->pdev);
+ intel_uncore_sanitize(dev);
+
/*
* Platforms with opregion should have sane BIOS, older ones (gen3 and
- * earlier) need to restore the GTT mappings since the BIOS might clear
- * all our scratch PTEs.
+ * earlier) need this since the BIOS might clear all our scratch PTEs.
*/
- ret = __i915_drm_thaw(dev, !dev_priv->opregion.header);
+ if (drm_core_check_feature(dev, DRIVER_MODESET) &&
+ !dev_priv->opregion.header) {
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_restore_gtt_mappings(dev);
+ mutex_unlock(&dev->struct_mutex);
+ }
+
+ ret = __i915_drm_thaw(dev);
if (ret)
return ret;
@@ -754,19 +722,24 @@ int i915_reset(struct drm_device *dev)
simulated = dev_priv->gpu_error.stop_rings != 0;
- ret = intel_gpu_reset(dev);
-
- /* Also reset the gpu hangman. */
- if (simulated) {
- DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
- dev_priv->gpu_error.stop_rings = 0;
- if (ret == -ENODEV) {
- DRM_ERROR("Reset not implemented, but ignoring "
- "error for simulated gpu hangs\n");
- ret = 0;
- }
+ if (!simulated && get_seconds() - dev_priv->gpu_error.last_reset < 5) {
+ DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
+ ret = -ENODEV;
+ } else {
+ ret = intel_gpu_reset(dev);
+
+ /* Also reset the gpu hangman. */
+ if (simulated) {
+ DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
+ dev_priv->gpu_error.stop_rings = 0;
+ if (ret == -ENODEV) {
+ DRM_ERROR("Reset not implemented, but ignoring "
+ "error for simulated gpu hangs\n");
+ ret = 0;
+ }
+ } else
+ dev_priv->gpu_error.last_reset = get_seconds();
}
-
if (ret) {
DRM_ERROR("Failed to reset chip.\n");
mutex_unlock(&dev->struct_mutex);
@@ -789,18 +762,31 @@ int i915_reset(struct drm_device *dev)
*/
if (drm_core_check_feature(dev, DRIVER_MODESET) ||
!dev_priv->ums.mm_suspended) {
- bool hw_contexts_disabled = dev_priv->hw_contexts_disabled;
+ struct intel_ring_buffer *ring;
+ int i;
+
dev_priv->ums.mm_suspended = 0;
- ret = i915_gem_init_hw(dev);
- if (!hw_contexts_disabled && dev_priv->hw_contexts_disabled)
- DRM_ERROR("HW contexts didn't survive reset\n");
- mutex_unlock(&dev->struct_mutex);
- if (ret) {
- DRM_ERROR("Failed hw init on reset %d\n", ret);
- return ret;
+ i915_gem_init_swizzling(dev);
+
+ for_each_ring(ring, dev_priv, i)
+ ring->init(ring);
+
+ i915_gem_context_init(dev);
+ if (dev_priv->mm.aliasing_ppgtt) {
+ ret = dev_priv->mm.aliasing_ppgtt->enable(dev);
+ if (ret)
+ i915_gem_cleanup_aliasing_ppgtt(dev);
}
+ /*
+ * It would make sense to re-init all the other hw state, at
+ * least the rps/rc6/emon init done within modeset_init_hw. For
+ * some unknown reason, this blows up my ilk, so don't.
+ */
+
+ mutex_unlock(&dev->struct_mutex);
+
drm_irq_uninstall(dev);
drm_irq_install(dev);
intel_hpd_init(dev);
@@ -816,12 +802,6 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct intel_device_info *intel_info =
(struct intel_device_info *) ent->driver_data;
- if (IS_PRELIMINARY_HW(intel_info) && !i915_preliminary_hw_support) {
- DRM_INFO("This hardware requires preliminary hardware support.\n"
- "See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or modparam preliminary_hw_support\n");
- return -ENODEV;
- }
-
/* Only bind to function 0 of the device. Early generations
* used function 1 as a placeholder for multi-head. This causes
* us confusion instead, especially on the systems where both
@@ -969,6 +949,7 @@ static struct drm_driver driver = {
.debugfs_init = i915_debugfs_init,
.debugfs_cleanup = i915_debugfs_cleanup,
#endif
+ .gem_init_object = i915_gem_init_object,
.gem_free_object = i915_gem_free_object,
.gem_vm_ops = &i915_gem_vm_ops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ccdbecc..ab0f2c0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -54,7 +54,6 @@
#define DRIVER_DATE "20080730"
enum pipe {
- INVALID_PIPE = -1,
PIPE_A = 0,
PIPE_B,
PIPE_C,
@@ -99,29 +98,13 @@ enum intel_display_power_domain {
POWER_DOMAIN_TRANSCODER_A,
POWER_DOMAIN_TRANSCODER_B,
POWER_DOMAIN_TRANSCODER_C,
- POWER_DOMAIN_TRANSCODER_EDP,
- POWER_DOMAIN_VGA,
- POWER_DOMAIN_INIT,
-
- POWER_DOMAIN_NUM,
+ POWER_DOMAIN_TRANSCODER_EDP = POWER_DOMAIN_TRANSCODER_A + 0xF,
};
-#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
-
#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
-#define POWER_DOMAIN_TRANSCODER(tran) \
- ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
- (tran) + POWER_DOMAIN_TRANSCODER_A)
-
-#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
- BIT(POWER_DOMAIN_PIPE_A) | \
- BIT(POWER_DOMAIN_TRANSCODER_EDP))
-#define BDW_ALWAYS_ON_POWER_DOMAINS ( \
- BIT(POWER_DOMAIN_PIPE_A) | \
- BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
- BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER))
+#define POWER_DOMAIN_TRANSCODER(tran) ((tran) + POWER_DOMAIN_TRANSCODER_A)
enum hpd_pin {
HPD_NONE = 0,
@@ -242,12 +225,9 @@ struct intel_opregion {
struct opregion_header __iomem *header;
struct opregion_acpi __iomem *acpi;
struct opregion_swsci __iomem *swsci;
- u32 swsci_gbda_sub_functions;
- u32 swsci_sbcb_sub_functions;
struct opregion_asle __iomem *asle;
void __iomem *vbt;
u32 __iomem *lid_state;
- struct work_struct asle_work;
};
#define OPREGION_SIZE (8*1024)
@@ -305,7 +285,6 @@ struct drm_i915_error_state {
u32 cpu_ring_tail[I915_NUM_RINGS];
u32 error; /* gen6+ */
u32 err_int; /* gen7 */
- u32 bbstate[I915_NUM_RINGS];
u32 instpm[I915_NUM_RINGS];
u32 instps[I915_NUM_RINGS];
u32 extra_instdone[I915_NUM_INSTDONE_REG];
@@ -342,13 +321,11 @@ struct drm_i915_error_state {
u32 dirty:1;
u32 purgeable:1;
s32 ring:4;
- u32 cache_level:3;
+ u32 cache_level:2;
} **active_bo, **pinned_bo;
u32 *active_bo_count, *pinned_bo_count;
struct intel_overlay_error_state *overlay;
struct intel_display_error_state *display;
- int hangcheck_score[I915_NUM_RINGS];
- enum intel_ring_hangcheck_action hangcheck_action[I915_NUM_RINGS];
};
struct intel_crtc_config;
@@ -380,7 +357,7 @@ struct drm_i915_display_funcs {
int target, int refclk,
struct dpll *match_clock,
struct dpll *best_clock);
- void (*update_wm)(struct drm_crtc *crtc);
+ void (*update_wm)(struct drm_device *dev);
void (*update_sprite_wm)(struct drm_plane *plane,
struct drm_crtc *crtc,
uint32_t sprite_width, int pixel_size,
@@ -390,6 +367,7 @@ struct drm_i915_display_funcs {
* fills out the pipe-config with the hw state. */
bool (*get_pipe_config)(struct intel_crtc *,
struct intel_crtc_config *);
+ void (*get_clock)(struct intel_crtc *, struct intel_crtc_config *);
int (*crtc_mode_set)(struct drm_crtc *crtc,
int x, int y,
struct drm_framebuffer *old_fb);
@@ -397,8 +375,7 @@ struct drm_i915_display_funcs {
void (*crtc_disable)(struct drm_crtc *crtc);
void (*off)(struct drm_crtc *crtc);
void (*write_eld)(struct drm_connector *connector,
- struct drm_crtc *crtc,
- struct drm_display_mode *mode);
+ struct drm_crtc *crtc);
void (*fdi_link_train)(struct drm_crtc *crtc);
void (*init_clock_gating)(struct drm_device *dev);
int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
@@ -418,20 +395,6 @@ struct drm_i915_display_funcs {
struct intel_uncore_funcs {
void (*force_wake_get)(struct drm_i915_private *dev_priv);
void (*force_wake_put)(struct drm_i915_private *dev_priv);
-
- uint8_t (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
- uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
- uint32_t (*mmio_readl)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
- uint64_t (*mmio_readq)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
-
- void (*mmio_writeb)(struct drm_i915_private *dev_priv, off_t offset,
- uint8_t val, bool trace);
- void (*mmio_writew)(struct drm_i915_private *dev_priv, off_t offset,
- uint16_t val, bool trace);
- void (*mmio_writel)(struct drm_i915_private *dev_priv, off_t offset,
- uint32_t val, bool trace);
- void (*mmio_writeq)(struct drm_i915_private *dev_priv, off_t offset,
- uint64_t val, bool trace);
};
struct intel_uncore {
@@ -441,8 +404,6 @@ struct intel_uncore {
unsigned fifo_count;
unsigned forcewake_count;
-
- struct delayed_work force_wake_work;
};
#define DEV_INFO_FOR_EACH_FLAG(func, sep) \
@@ -459,7 +420,7 @@ struct intel_uncore {
func(is_ivybridge) sep \
func(is_valleyview) sep \
func(is_haswell) sep \
- func(is_preliminary) sep \
+ func(has_force_wake) sep \
func(has_fbc) sep \
func(has_pipe_cxsr) sep \
func(has_hotplug) sep \
@@ -467,6 +428,9 @@ struct intel_uncore {
func(has_overlay) sep \
func(overlay_needs_physical) sep \
func(supports_tv) sep \
+ func(has_bsd_ring) sep \
+ func(has_blt_ring) sep \
+ func(has_vebox_ring) sep \
func(has_llc) sep \
func(has_ddi) sep \
func(has_fpga_dbg)
@@ -478,7 +442,6 @@ struct intel_device_info {
u32 display_mmio_offset;
u8 num_pipes:3;
u8 gen;
- u8 ring_mask; /* Rings supported by the HW */
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
};
@@ -579,21 +542,10 @@ struct i915_gtt {
struct i915_hw_ppgtt {
struct i915_address_space base;
unsigned num_pd_entries;
- union {
- struct page **pt_pages;
- struct page *gen8_pt_pages;
- };
- struct page *pd_pages;
- int num_pd_pages;
- int num_pt_pages;
- union {
- uint32_t pd_offset;
- dma_addr_t pd_dma_addr[4];
- };
- union {
- dma_addr_t *pt_dma_addr;
- dma_addr_t *gen8_pt_dma_addr[4];
- };
+ struct page **pt_pages;
+ uint32_t pd_offset;
+ dma_addr_t *pt_dma_addr;
+
int (*enable)(struct drm_device *dev);
};
@@ -618,13 +570,6 @@ struct i915_vma {
/** This vma's place in the batchbuffer or on the eviction list */
struct list_head exec_list;
- /**
- * Used for performing relocations during execbuffer insertion.
- */
- struct hlist_node exec_node;
- unsigned long exec_handle;
- struct drm_i915_gem_exec_object2 *exec_entry;
-
};
struct i915_ctx_hang_stats {
@@ -633,12 +578,6 @@ struct i915_ctx_hang_stats {
/* This context had batch active when hang was declared */
unsigned batch_active;
-
- /* Time when this context was last blamed for a GPU reset */
- unsigned long guilty_ts;
-
- /* This context is banned to submit more work */
- bool banned;
};
/* This must match up with the value previously used for execbuf2.rsvd1. */
@@ -647,13 +586,10 @@ struct i915_hw_context {
struct kref ref;
int id;
bool is_initialized;
- uint8_t remap_slice;
struct drm_i915_file_private *file_priv;
struct intel_ring_buffer *ring;
struct drm_i915_gem_object *obj;
struct i915_ctx_hang_stats hang_stats;
-
- struct list_head link;
};
struct i915_fbc {
@@ -687,9 +623,17 @@ struct i915_fbc {
} no_fbc_reason;
};
-struct i915_psr {
- bool sink_support;
- bool source_ok;
+enum no_psr_reason {
+ PSR_NO_SOURCE, /* Not supported on platform */
+ PSR_NO_SINK, /* Not supported by panel */
+ PSR_MODULE_PARAM,
+ PSR_CRTC_NOT_ACTIVE,
+ PSR_PWR_WELL_ENABLED,
+ PSR_NOT_TILED,
+ PSR_SPRITE_ENABLED,
+ PSR_S3D_ENABLED,
+ PSR_INTERLACED_ENABLED,
+ PSR_HSW_NOT_DDIA,
};
enum intel_pch {
@@ -760,9 +704,6 @@ struct i915_suspend_saved_registers {
u32 saveBLC_HIST_CTL;
u32 saveBLC_PWM_CTL;
u32 saveBLC_PWM_CTL2;
- u32 saveBLC_HIST_CTL_B;
- u32 saveBLC_PWM_CTL_B;
- u32 saveBLC_PWM_CTL2_B;
u32 saveBLC_CPU_PWM_CTL;
u32 saveBLC_CPU_PWM_CTL2;
u32 saveFPB0;
@@ -882,20 +823,17 @@ struct intel_gen6_power_mgmt {
struct work_struct work;
u32 pm_iir;
+ /* On vlv we need to manually drop to Vmin with a delayed work. */
+ struct delayed_work vlv_work;
+
/* The below variables an all the rps hw state are protected by
* dev->struct mutext. */
u8 cur_delay;
u8 min_delay;
u8 max_delay;
u8 rpe_delay;
- u8 rp1_delay;
- u8 rp0_delay;
u8 hw_max;
- int last_adj;
- enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
-
- bool enabled;
struct delayed_work delayed_resume_work;
/*
@@ -932,21 +870,11 @@ struct intel_ilk_power_mgmt {
/* Power well structure for haswell */
struct i915_power_well {
+ struct drm_device *device;
+ spinlock_t lock;
/* power well enable/disable usage count */
int count;
-};
-
-#define I915_MAX_POWER_WELLS 1
-
-struct i915_power_domains {
- /*
- * Power wells needed for initialization at driver init and suspend
- * time are on. They are kept on until after the first modeset.
- */
- bool init_power_on;
-
- struct mutex lock;
- struct i915_power_well power_wells[I915_MAX_POWER_WELLS];
+ int i915_request;
};
struct i915_dri1_state {
@@ -974,11 +902,9 @@ struct i915_ums_state {
int mm_suspended;
};
-#define MAX_L3_SLICES 2
struct intel_l3_parity {
- u32 *remap_info[MAX_L3_SLICES];
+ u32 *remap_info;
struct work_struct error_work;
- int which_slice;
};
struct i915_gem_mm {
@@ -1016,15 +942,6 @@ struct i915_gem_mm {
struct delayed_work retire_work;
/**
- * When we detect an idle GPU, we want to turn on
- * powersaving features. So once we see that there
- * are no more requests outstanding and no more
- * arrive within a small period of time, we fire
- * off the idle_work.
- */
- struct delayed_work idle_work;
-
- /**
* Are we in a non-interruptible section of code like
* modesetting?
*/
@@ -1062,9 +979,6 @@ struct i915_gpu_error {
/* For hangcheck timer */
#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
#define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
- /* Hang gpu twice in this window and your context gets banned */
-#define DRM_I915_CTX_BAN_PERIOD DIV_ROUND_UP(8*DRM_I915_HANGCHECK_PERIOD, 1000)
-
struct timer_list hangcheck_timer;
/* For reset and error_state handling. */
@@ -1073,8 +987,7 @@ struct i915_gpu_error {
struct drm_i915_error_state *first_error;
struct work_struct work;
-
- unsigned long missed_irq_rings;
+ unsigned long last_reset;
/**
* State variable and reset counter controlling the reset flow
@@ -1114,9 +1027,6 @@ struct i915_gpu_error {
/* For gpu hang simulation. */
unsigned int stop_rings;
-
- /* For missed irq/seqno simulation. */
- unsigned int test_irq_rings;
};
enum modeset_restore {
@@ -1125,14 +1035,6 @@ enum modeset_restore {
MODESET_SUSPENDED,
};
-struct ddi_vbt_port_info {
- uint8_t hdmi_level_shift;
-
- uint8_t supports_dvi:1;
- uint8_t supports_hdmi:1;
- uint8_t supports_dp:1;
-};
-
struct intel_vbt_data {
struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
@@ -1158,17 +1060,10 @@ struct intel_vbt_data {
int edp_bpp;
struct edp_power_seq edp_pps;
- /* MIPI DSI */
- struct {
- u16 panel_id;
- } dsi;
-
int crt_ddc_pin;
int child_dev_num;
- union child_device_config *child_dev;
-
- struct ddi_vbt_port_info ddi_port_info[I915_MAX_PORTS];
+ struct child_device_config *child_dev;
};
enum intel_ddb_partitioning {
@@ -1184,15 +1079,6 @@ struct intel_wm_level {
uint32_t fbc_val;
};
-struct hsw_wm_values {
- uint32_t wm_pipe[3];
- uint32_t wm_lp[3];
- uint32_t wm_lp_spr[3];
- uint32_t wm_linetime[3];
- bool enable_fbc_wm;
- enum intel_ddb_partitioning partitioning;
-};
-
/*
* This struct tracks the state needed for the Package C8+ feature.
*
@@ -1262,36 +1148,6 @@ struct i915_package_c8 {
} regsave;
};
-enum intel_pipe_crc_source {
- INTEL_PIPE_CRC_SOURCE_NONE,
- INTEL_PIPE_CRC_SOURCE_PLANE1,
- INTEL_PIPE_CRC_SOURCE_PLANE2,
- INTEL_PIPE_CRC_SOURCE_PF,
- INTEL_PIPE_CRC_SOURCE_PIPE,
- /* TV/DP on pre-gen5/vlv can't use the pipe source. */
- INTEL_PIPE_CRC_SOURCE_TV,
- INTEL_PIPE_CRC_SOURCE_DP_B,
- INTEL_PIPE_CRC_SOURCE_DP_C,
- INTEL_PIPE_CRC_SOURCE_DP_D,
- INTEL_PIPE_CRC_SOURCE_AUTO,
- INTEL_PIPE_CRC_SOURCE_MAX,
-};
-
-struct intel_pipe_crc_entry {
- uint32_t frame;
- uint32_t crc[5];
-};
-
-#define INTEL_PIPE_CRC_ENTRIES_NR 128
-struct intel_pipe_crc {
- spinlock_t lock;
- bool opened; /* exclusive access to the result file */
- struct intel_pipe_crc_entry *entries;
- enum intel_pipe_crc_source source;
- int head, tail;
- wait_queue_head_t wq;
-};
-
typedef struct drm_i915_private {
struct drm_device *dev;
struct kmem_cache *slab;
@@ -1337,10 +1193,7 @@ typedef struct drm_i915_private {
struct mutex dpio_lock;
/** Cached value of IMR to avoid reads in updating the bitfield */
- union {
- u32 irq_mask;
- u32 de_irq_mask[I915_MAX_PIPES];
- };
+ u32 irq_mask;
u32 gt_irq_mask;
u32 pm_irq_mask;
@@ -1419,10 +1272,6 @@ typedef struct drm_i915_private {
struct drm_crtc *pipe_to_crtc_mapping[3];
wait_queue_head_t pending_flip_queue;
-#ifdef CONFIG_DEBUG_FS
- struct intel_pipe_crc pipe_crc[I915_MAX_PIPES];
-#endif
-
int num_shared_dpll;
struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
struct intel_ddi_plls ddi_plls;
@@ -1448,18 +1297,17 @@ typedef struct drm_i915_private {
* mchdev_lock in intel_pm.c */
struct intel_ilk_power_mgmt ips;
- struct i915_power_domains power_domains;
+ /* Haswell power well */
+ struct i915_power_well power_well;
- struct i915_psr psr;
+ enum no_psr_reason no_psr_reason;
struct i915_gpu_error gpu_error;
struct drm_i915_gem_object *vlv_pctx;
-#ifdef CONFIG_DRM_I915_FBDEV
/* list of fbdev register on this device */
struct intel_fbdev *fbdev;
-#endif
/*
* The console may be contended at resume, but we don't
@@ -1472,7 +1320,6 @@ typedef struct drm_i915_private {
bool hw_contexts_disabled;
uint32_t hw_context_size;
- struct list_head context_list;
u32 fdi_rx_config;
@@ -1490,9 +1337,6 @@ typedef struct drm_i915_private {
uint16_t spr_latency[5];
/* cursor */
uint16_t cur_latency[5];
-
- /* current hardware state */
- struct hsw_wm_values hw;
} wm;
struct i915_package_c8 pc8;
@@ -1556,6 +1400,8 @@ struct drm_i915_gem_object {
struct list_head ring_list;
/** Used in execbuf to temporarily hold a ref */
struct list_head obj_exec_link;
+ /** This object's place in the batchbuffer or on the eviction list */
+ struct list_head exec_list;
/**
* This is set if the object is on the active lists (has pending
@@ -1641,6 +1487,13 @@ struct drm_i915_gem_object {
void *dma_buf_vmapping;
int vmapping_count;
+ /**
+ * Used for performing relocations during execbuffer insertion.
+ */
+ struct hlist_node exec_node;
+ unsigned long exec_handle;
+ struct drm_i915_gem_exec_object2 *exec_entry;
+
struct intel_ring_buffer *ring;
/** Breadcrumb of last rendering to the buffer. */
@@ -1652,14 +1505,11 @@ struct drm_i915_gem_object {
/** Current tiling stride for the object, if it's tiled. */
uint32_t stride;
- /** References from framebuffers, locks out tiling changes. */
- unsigned long framebuffer_references;
-
/** Record of address bit 17 of each page at last unbind. */
unsigned long *bit_17;
/** User space pin count and filp owning the pin */
- unsigned long user_pin_count;
+ uint32_t user_pin_count;
struct drm_file *pin_filp;
/** for phy allocated objects */
@@ -1710,56 +1560,48 @@ struct drm_i915_gem_request {
};
struct drm_i915_file_private {
- struct drm_i915_private *dev_priv;
-
struct {
spinlock_t lock;
struct list_head request_list;
- struct delayed_work idle_work;
} mm;
struct idr context_idr;
struct i915_ctx_hang_stats hang_stats;
- atomic_t rps_wait_boost;
};
#define INTEL_INFO(dev) (to_i915(dev)->info)
-#define IS_I830(dev) ((dev)->pdev->device == 0x3577)
-#define IS_845G(dev) ((dev)->pdev->device == 0x2562)
+#define IS_I830(dev) ((dev)->pci_device == 0x3577)
+#define IS_845G(dev) ((dev)->pci_device == 0x2562)
#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x)
-#define IS_I865G(dev) ((dev)->pdev->device == 0x2572)
+#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g)
-#define IS_I915GM(dev) ((dev)->pdev->device == 0x2592)
-#define IS_I945G(dev) ((dev)->pdev->device == 0x2772)
+#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
+#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
#define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm)
#define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater)
#define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline)
-#define IS_GM45(dev) ((dev)->pdev->device == 0x2A42)
+#define IS_GM45(dev) ((dev)->pci_device == 0x2A42)
#define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x)
-#define IS_PINEVIEW_G(dev) ((dev)->pdev->device == 0xa001)
-#define IS_PINEVIEW_M(dev) ((dev)->pdev->device == 0xa011)
+#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001)
+#define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011)
#define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview)
#define IS_G33(dev) (INTEL_INFO(dev)->is_g33)
-#define IS_IRONLAKE_M(dev) ((dev)->pdev->device == 0x0046)
+#define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046)
#define IS_IVYBRIDGE(dev) (INTEL_INFO(dev)->is_ivybridge)
-#define IS_IVB_GT1(dev) ((dev)->pdev->device == 0x0156 || \
- (dev)->pdev->device == 0x0152 || \
- (dev)->pdev->device == 0x015a)
-#define IS_SNB_GT1(dev) ((dev)->pdev->device == 0x0102 || \
- (dev)->pdev->device == 0x0106 || \
- (dev)->pdev->device == 0x010A)
+#define IS_IVB_GT1(dev) ((dev)->pci_device == 0x0156 || \
+ (dev)->pci_device == 0x0152 || \
+ (dev)->pci_device == 0x015a)
+#define IS_SNB_GT1(dev) ((dev)->pci_device == 0x0102 || \
+ (dev)->pci_device == 0x0106 || \
+ (dev)->pci_device == 0x010A)
#define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview)
#define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell)
-#define IS_BROADWELL(dev) (INTEL_INFO(dev)->gen == 8)
#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile)
#define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \
- ((dev)->pdev->device & 0xFF00) == 0x0C00)
+ ((dev)->pci_device & 0xFF00) == 0x0C00)
#define IS_ULT(dev) (IS_HASWELL(dev) && \
- ((dev)->pdev->device & 0xFF00) == 0x0A00)
-#define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \
- ((dev)->pdev->device & 0x00F0) == 0x0020)
-#define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
+ ((dev)->pci_device & 0xFF00) == 0x0A00)
/*
* The genX designation typically refers to the render engine, so render
@@ -1773,15 +1615,10 @@ struct drm_i915_file_private {
#define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5)
#define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6)
#define IS_GEN7(dev) (INTEL_INFO(dev)->gen == 7)
-#define IS_GEN8(dev) (INTEL_INFO(dev)->gen == 8)
-
-#define RENDER_RING (1<<RCS)
-#define BSD_RING (1<<VCS)
-#define BLT_RING (1<<BCS)
-#define VEBOX_RING (1<<VECS)
-#define HAS_BSD(dev) (INTEL_INFO(dev)->ring_mask & BSD_RING)
-#define HAS_BLT(dev) (INTEL_INFO(dev)->ring_mask & BLT_RING)
-#define HAS_VEBOX(dev) (INTEL_INFO(dev)->ring_mask & VEBOX_RING)
+
+#define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring)
+#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring)
+#define HAS_VEBOX(dev) (INTEL_INFO(dev)->has_vebox_ring)
#define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc)
#define HAS_WT(dev) (IS_HASWELL(dev) && to_i915(dev)->ellc_size)
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
@@ -1803,6 +1640,7 @@ struct drm_i915_file_private {
#define SUPPORTS_DIGITAL_OUTPUTS(dev) (!IS_GEN2(dev) && !IS_PINEVIEW(dev))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_GEN5(dev))
#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_GEN5(dev))
+#define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev))
#define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv)
#define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug)
@@ -1810,13 +1648,11 @@ struct drm_i915_file_private {
#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr)
#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
-#define HAS_IPS(dev) (IS_ULT(dev) || IS_BROADWELL(dev))
+#define HAS_IPS(dev) (IS_ULT(dev))
#define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi)
-#define HAS_POWER_WELL(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev))
+#define HAS_POWER_WELL(dev) (IS_HASWELL(dev))
#define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg)
-#define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev))
-#define HAS_PC8(dev) (IS_HASWELL(dev)) /* XXX HSW:ULX */
#define INTEL_PCH_DEVICE_ID_MASK 0xff00
#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00
@@ -1832,14 +1668,35 @@ struct drm_i915_file_private {
#define HAS_PCH_NOP(dev) (INTEL_PCH_TYPE(dev) == PCH_NOP)
#define HAS_PCH_SPLIT(dev) (INTEL_PCH_TYPE(dev) != PCH_NONE)
-/* DPF == dynamic parity feature */
-#define HAS_L3_DPF(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
-#define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_DPF(dev))
+#define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)
+
+#define HAS_L3_GPU_CACHE(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
#define GT_FREQUENCY_MULTIPLIER 50
#include "i915_trace.h"
+/**
+ * RC6 is a special power stage which allows the GPU to enter an very
+ * low-voltage mode when idle, using down to 0V while at this stage. This
+ * stage is entered automatically when the GPU is idle when RC6 support is
+ * enabled, and as soon as new workload arises GPU wakes up automatically as well.
+ *
+ * There are different RC6 modes available in Intel GPU, which differentiate
+ * among each other with the latency required to enter and leave RC6 and
+ * voltage consumed by the GPU in different states.
+ *
+ * The combination of the following flags define which states GPU is allowed
+ * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and
+ * RC6pp is deepest RC6. Their support by hardware varies according to the
+ * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one
+ * which brings the most power savings; deeper states save more power, but
+ * require higher latency to switch to and wake up.
+ */
+#define INTEL_RC6_ENABLE (1<<0)
+#define INTEL_RC6p_ENABLE (1<<1)
+#define INTEL_RC6pp_ENABLE (1<<2)
+
extern const struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl;
extern unsigned int i915_fbpercrtc __always_unused;
@@ -1910,13 +1767,12 @@ extern void intel_uncore_early_sanitize(struct drm_device *dev);
extern void intel_uncore_init(struct drm_device *dev);
extern void intel_uncore_clear_errors(struct drm_device *dev);
extern void intel_uncore_check_errors(struct drm_device *dev);
-extern void intel_uncore_fini(struct drm_device *dev);
void
-i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask);
+i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
void
-i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask);
+i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
/* i915_gem.c */
int i915_gem_init_ioctl(struct drm_device *dev, void *data,
@@ -1968,11 +1824,14 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
void i915_gem_load(struct drm_device *dev);
void *i915_gem_object_alloc(struct drm_device *dev);
void i915_gem_object_free(struct drm_i915_gem_object *obj);
+int i915_gem_init_object(struct drm_gem_object *obj);
void i915_gem_object_init(struct drm_i915_gem_object *obj,
const struct drm_i915_gem_object_ops *ops);
struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
size_t size);
void i915_gem_free_object(struct drm_gem_object *obj);
+struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm);
void i915_gem_vma_destroy(struct i915_vma *vma);
int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
@@ -2011,8 +1870,9 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
int i915_gem_object_sync(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *to);
-void i915_vma_move_to_active(struct i915_vma *vma,
- struct intel_ring_buffer *ring);
+void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
+ struct intel_ring_buffer *ring);
+
int i915_gem_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -2053,7 +1913,7 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
}
}
-bool i915_gem_retire_requests(struct drm_device *dev);
+void i915_gem_retire_requests(struct drm_device *dev);
void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring);
int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
bool interruptible);
@@ -2073,11 +1933,11 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj);
int __must_check i915_gem_init(struct drm_device *dev);
int __must_check i915_gem_init_hw(struct drm_device *dev);
-int i915_gem_l3_remap(struct intel_ring_buffer *ring, int slice);
+void i915_gem_l3_remap(struct drm_device *dev);
void i915_gem_init_swizzling(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int __must_check i915_gpu_idle(struct drm_device *dev);
-int __must_check i915_gem_suspend(struct drm_device *dev);
+int __must_check i915_gem_idle(struct drm_device *dev);
int __i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
struct drm_i915_gem_object *batch_obj,
@@ -2104,7 +1964,6 @@ int i915_gem_attach_phys_object(struct drm_device *dev,
void i915_gem_detach_phys_object(struct drm_device *dev,
struct drm_i915_gem_object *obj);
void i915_gem_free_all_phys_object(struct drm_device *dev);
-int i915_gem_open(struct drm_device *dev, struct drm_file *file);
void i915_gem_release(struct drm_device *dev, struct drm_file *file);
uint32_t
@@ -2136,9 +1995,6 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
struct i915_vma *
i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm);
-
-struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj);
-
/* Some GGTT VM helpers */
#define obj_to_ggtt(obj) \
(&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base)
@@ -2175,6 +2031,7 @@ i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj,
return i915_gem_object_pin(obj, obj_to_ggtt(obj), alignment,
map_and_fenceable, nonblocking);
}
+#undef obj_to_ggtt
/* i915_gem_context.c */
void i915_gem_context_init(struct drm_device *dev);
@@ -2237,7 +2094,6 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,
unsigned cache_level,
bool mappable,
bool nonblock);
-int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
int i915_gem_evict_everything(struct drm_device *dev);
/* i915_gem_stolen.c */
@@ -2277,11 +2133,6 @@ int i915_verify_lists(struct drm_device *dev);
/* i915_debugfs.c */
int i915_debugfs_init(struct drm_minor *minor);
void i915_debugfs_cleanup(struct drm_minor *minor);
-#ifdef CONFIG_DEBUG_FS
-void intel_display_crc_init(struct drm_device *dev);
-#else
-static inline void intel_display_crc_init(struct drm_device *dev) {}
-#endif
/* i915_gpu_error.c */
__printf(2, 3)
@@ -2335,30 +2186,15 @@ static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
extern void intel_i2c_reset(struct drm_device *dev);
/* intel_opregion.c */
-struct intel_encoder;
extern int intel_opregion_setup(struct drm_device *dev);
#ifdef CONFIG_ACPI
extern void intel_opregion_init(struct drm_device *dev);
extern void intel_opregion_fini(struct drm_device *dev);
extern void intel_opregion_asle_intr(struct drm_device *dev);
-extern int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
- bool enable);
-extern int intel_opregion_notify_adapter(struct drm_device *dev,
- pci_power_t state);
#else
static inline void intel_opregion_init(struct drm_device *dev) { return; }
static inline void intel_opregion_fini(struct drm_device *dev) { return; }
static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
-static inline int
-intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, bool enable)
-{
- return 0;
-}
-static inline int
-intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
-{
- return 0;
-}
#endif
/* intel_acpi.c */
@@ -2420,16 +2256,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr);
void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val);
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
-u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
-void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
+u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg);
+void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val);
u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
enum intel_sbi_destination destination);
void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
@@ -2438,21 +2266,37 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
int vlv_gpu_freq(int ddr_freq, int val);
int vlv_freq_opcode(int ddr_freq, int val);
-#define I915_READ8(reg) dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
-#define I915_WRITE8(reg, val) dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
-
-#define I915_READ16(reg) dev_priv->uncore.funcs.mmio_readw(dev_priv, (reg), true)
-#define I915_WRITE16(reg, val) dev_priv->uncore.funcs.mmio_writew(dev_priv, (reg), (val), true)
-#define I915_READ16_NOTRACE(reg) dev_priv->uncore.funcs.mmio_readw(dev_priv, (reg), false)
-#define I915_WRITE16_NOTRACE(reg, val) dev_priv->uncore.funcs.mmio_writew(dev_priv, (reg), (val), false)
-
-#define I915_READ(reg) dev_priv->uncore.funcs.mmio_readl(dev_priv, (reg), true)
-#define I915_WRITE(reg, val) dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), true)
-#define I915_READ_NOTRACE(reg) dev_priv->uncore.funcs.mmio_readl(dev_priv, (reg), false)
-#define I915_WRITE_NOTRACE(reg, val) dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), false)
-
-#define I915_WRITE64(reg, val) dev_priv->uncore.funcs.mmio_writeq(dev_priv, (reg), (val), true)
-#define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true)
+#define __i915_read(x) \
+ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg, bool trace);
+__i915_read(8)
+__i915_read(16)
+__i915_read(32)
+__i915_read(64)
+#undef __i915_read
+
+#define __i915_write(x) \
+ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val, bool trace);
+__i915_write(8)
+__i915_write(16)
+__i915_write(32)
+__i915_write(64)
+#undef __i915_write
+
+#define I915_READ8(reg) i915_read8(dev_priv, (reg), true)
+#define I915_WRITE8(reg, val) i915_write8(dev_priv, (reg), (val), true)
+
+#define I915_READ16(reg) i915_read16(dev_priv, (reg), true)
+#define I915_WRITE16(reg, val) i915_write16(dev_priv, (reg), (val), true)
+#define I915_READ16_NOTRACE(reg) i915_read16(dev_priv, (reg), false)
+#define I915_WRITE16_NOTRACE(reg, val) i915_write16(dev_priv, (reg), (val), false)
+
+#define I915_READ(reg) i915_read32(dev_priv, (reg), true)
+#define I915_WRITE(reg, val) i915_write32(dev_priv, (reg), (val), true)
+#define I915_READ_NOTRACE(reg) i915_read32(dev_priv, (reg), false)
+#define I915_WRITE_NOTRACE(reg, val) i915_write32(dev_priv, (reg), (val), false)
+
+#define I915_WRITE64(reg, val) i915_write64(dev_priv, (reg), (val), true)
+#define I915_READ64(reg) i915_read64(dev_priv, (reg), true)
#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 621c7c6..cdfb9da 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -41,9 +41,6 @@ static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *o
static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj,
bool force);
static __must_check int
-i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
- bool readonly);
-static __must_check int
i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
unsigned alignment,
@@ -64,8 +61,8 @@ static unsigned long i915_gem_inactive_count(struct shrinker *shrinker,
struct shrink_control *sc);
static unsigned long i915_gem_inactive_scan(struct shrinker *shrinker,
struct shrink_control *sc);
-static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
-static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
+static long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
+static long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
static bool cpu_cache_is_coherent(struct drm_device *dev,
@@ -261,7 +258,7 @@ i915_gem_dumb_create(struct drm_file *file,
struct drm_mode_create_dumb *args)
{
/* have to work out size/pitch and return them */
- args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
+ args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
args->size = args->pitch * args->height;
return i915_gem_create(file, dev,
args->size, &args->handle);
@@ -435,9 +432,11 @@ i915_gem_shmem_pread(struct drm_device *dev,
* optimizes for the case when the gpu will dirty the data
* anyway again before the next pread happens. */
needs_clflush = !cpu_cache_is_coherent(dev, obj->cache_level);
- ret = i915_gem_object_wait_rendering(obj, true);
- if (ret)
- return ret;
+ if (i915_gem_obj_bound_any(obj)) {
+ ret = i915_gem_object_set_to_gtt_domain(obj, false);
+ if (ret)
+ return ret;
+ }
}
ret = i915_gem_object_get_pages(obj);
@@ -749,9 +748,11 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
* optimizes for the case when the gpu will use the data
* right away and we therefore have to clflush anyway. */
needs_clflush_after = cpu_write_needs_clflush(obj);
- ret = i915_gem_object_wait_rendering(obj, false);
- if (ret)
- return ret;
+ if (i915_gem_obj_bound_any(obj)) {
+ ret = i915_gem_object_set_to_gtt_domain(obj, true);
+ if (ret)
+ return ret;
+ }
}
/* Same trick applies to invalidate partially written cachelines read
* before writing. */
@@ -965,31 +966,12 @@ i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno)
BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
ret = 0;
- if (seqno == ring->outstanding_lazy_seqno)
+ if (seqno == ring->outstanding_lazy_request)
ret = i915_add_request(ring, NULL);
return ret;
}
-static void fake_irq(unsigned long data)
-{
- wake_up_process((struct task_struct *)data);
-}
-
-static bool missed_irq(struct drm_i915_private *dev_priv,
- struct intel_ring_buffer *ring)
-{
- return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
-}
-
-static bool can_wait_boost(struct drm_i915_file_private *file_priv)
-{
- if (file_priv == NULL)
- return true;
-
- return !atomic_xchg(&file_priv->rps_wait_boost, true);
-}
-
/**
* __wait_seqno - wait until execution of seqno has finished
* @ring: the ring expected to report seqno
@@ -1010,14 +992,13 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
*/
static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
unsigned reset_counter,
- bool interruptible,
- struct timespec *timeout,
- struct drm_i915_file_private *file_priv)
+ bool interruptible, struct timespec *timeout)
{
drm_i915_private_t *dev_priv = ring->dev->dev_private;
- struct timespec before, now;
- DEFINE_WAIT(wait);
- long timeout_jiffies;
+ struct timespec before, now, wait_time={1,0};
+ unsigned long timeout_jiffies;
+ long end;
+ bool wait_forever = true;
int ret;
WARN(dev_priv->pc8.irqs_disabled, "IRQs disabled\n");
@@ -1025,79 +1006,51 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
return 0;
- timeout_jiffies = timeout ? timespec_to_jiffies_timeout(timeout) : 1;
+ trace_i915_gem_request_wait_begin(ring, seqno);
- if (dev_priv->info->gen >= 6 && can_wait_boost(file_priv)) {
- gen6_rps_boost(dev_priv);
- if (file_priv)
- mod_delayed_work(dev_priv->wq,
- &file_priv->mm.idle_work,
- msecs_to_jiffies(100));
+ if (timeout != NULL) {
+ wait_time = *timeout;
+ wait_forever = false;
}
- if (!(dev_priv->gpu_error.test_irq_rings & intel_ring_flag(ring)) &&
- WARN_ON(!ring->irq_get(ring)))
+ timeout_jiffies = timespec_to_jiffies_timeout(&wait_time);
+
+ if (WARN_ON(!ring->irq_get(ring)))
return -ENODEV;
- /* Record current time in case interrupted by signal, or wedged */
- trace_i915_gem_request_wait_begin(ring, seqno);
+ /* Record current time in case interrupted by signal, or wedged * */
getrawmonotonic(&before);
- for (;;) {
- struct timer_list timer;
- unsigned long expire;
- prepare_to_wait(&ring->irq_queue, &wait,
- interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+#define EXIT_COND \
+ (i915_seqno_passed(ring->get_seqno(ring, false), seqno) || \
+ i915_reset_in_progress(&dev_priv->gpu_error) || \
+ reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
+ do {
+ if (interruptible)
+ end = wait_event_interruptible_timeout(ring->irq_queue,
+ EXIT_COND,
+ timeout_jiffies);
+ else
+ end = wait_event_timeout(ring->irq_queue, EXIT_COND,
+ timeout_jiffies);
/* We need to check whether any gpu reset happened in between
* the caller grabbing the seqno and now ... */
- if (reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) {
- /* ... but upgrade the -EAGAIN to an -EIO if the gpu
- * is truely gone. */
- ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
- if (ret == 0)
- ret = -EAGAIN;
- break;
- }
-
- if (i915_seqno_passed(ring->get_seqno(ring, false), seqno)) {
- ret = 0;
- break;
- }
+ if (reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
+ end = -EAGAIN;
- if (interruptible && signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
-
- if (timeout_jiffies <= 0) {
- ret = -ETIME;
- break;
- }
-
- timer.function = NULL;
- if (timeout || missed_irq(dev_priv, ring)) {
- setup_timer_on_stack(&timer, fake_irq, (unsigned long)current);
- expire = jiffies + (missed_irq(dev_priv, ring) ? 1: timeout_jiffies);
- mod_timer(&timer, expire);
- }
-
- io_schedule();
-
- if (timeout)
- timeout_jiffies = expire - jiffies;
+ /* ... but upgrade the -EGAIN to an -EIO if the gpu is truely
+ * gone. */
+ ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
+ if (ret)
+ end = ret;
+ } while (end == 0 && wait_forever);
- if (timer.function) {
- del_singleshot_timer_sync(&timer);
- destroy_timer_on_stack(&timer);
- }
- }
getrawmonotonic(&now);
- trace_i915_gem_request_wait_end(ring, seqno);
ring->irq_put(ring);
-
- finish_wait(&ring->irq_queue, &wait);
+ trace_i915_gem_request_wait_end(ring, seqno);
+#undef EXIT_COND
if (timeout) {
struct timespec sleep_time = timespec_sub(now, before);
@@ -1106,7 +1059,17 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
set_normalized_timespec(timeout, 0, 0);
}
- return ret;
+ switch (end) {
+ case -EIO:
+ case -EAGAIN: /* Wedged */
+ case -ERESTARTSYS: /* Signal */
+ return (int)end;
+ case 0: /* Timeout */
+ return -ETIME;
+ default: /* Completed */
+ WARN_ON(end < 0); /* We're not aware of other errors */
+ return 0;
+ }
}
/**
@@ -1134,7 +1097,7 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
return __wait_seqno(ring, seqno,
atomic_read(&dev_priv->gpu_error.reset_counter),
- interruptible, NULL, NULL);
+ interruptible, NULL);
}
static int
@@ -1184,7 +1147,6 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
*/
static __must_check int
i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
- struct drm_file *file,
bool readonly)
{
struct drm_device *dev = obj->base.dev;
@@ -1211,7 +1173,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
mutex_unlock(&dev->struct_mutex);
- ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, file->driver_priv);
+ ret = __wait_seqno(ring, seqno, reset_counter, true, NULL);
mutex_lock(&dev->struct_mutex);
if (ret)
return ret;
@@ -1260,7 +1222,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
* We will repeat the flush holding the lock in the normal manner
* to catch cases where we are gazumped.
*/
- ret = i915_gem_object_wait_rendering__nonblocking(obj, file, !write_domain);
+ ret = i915_gem_object_wait_rendering__nonblocking(obj, !write_domain);
if (ret)
goto unref;
@@ -1728,13 +1690,13 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
return 0;
}
-static unsigned long
+static long
__i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
bool purgeable_only)
{
struct list_head still_bound_list;
struct drm_i915_gem_object *obj, *next;
- unsigned long count = 0;
+ long count = 0;
list_for_each_entry_safe(obj, next,
&dev_priv->mm.unbound_list,
@@ -1800,13 +1762,13 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
return count;
}
-static unsigned long
+static long
i915_gem_purge(struct drm_i915_private *dev_priv, long target)
{
return __i915_gem_shrink(dev_priv, target, true);
}
-static unsigned long
+static long
i915_gem_shrink_all(struct drm_i915_private *dev_priv)
{
struct drm_i915_gem_object *obj, *next;
@@ -1816,8 +1778,9 @@ i915_gem_shrink_all(struct drm_i915_private *dev_priv)
list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list,
global_list) {
- if (i915_gem_object_put_pages(obj) == 0)
+ if (obj->pages_pin_count == 0)
freed += obj->base.size >> PAGE_SHIFT;
+ i915_gem_object_put_pages(obj);
}
return freed;
}
@@ -1902,9 +1865,6 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
sg->length += PAGE_SIZE;
}
last_pfn = page_to_pfn(page);
-
- /* Check that the i965g/gm workaround works. */
- WARN_ON((gfp & __GFP_DMA32) && (last_pfn >= 0x00100000UL));
}
#ifdef CONFIG_SWIOTLB
if (!swiotlb_nr_tbl())
@@ -1958,7 +1918,7 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
return 0;
}
-static void
+void
i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *ring)
{
@@ -1997,13 +1957,6 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
}
}
-void i915_vma_move_to_active(struct i915_vma *vma,
- struct intel_ring_buffer *ring)
-{
- list_move_tail(&vma->mm_list, &vma->vm->active_list);
- return i915_gem_object_move_to_active(vma->obj, ring);
-}
-
static void
i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
{
@@ -2125,10 +2078,11 @@ int __i915_add_request(struct intel_ring_buffer *ring,
if (ret)
return ret;
- request = ring->preallocated_lazy_request;
- if (WARN_ON(request == NULL))
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
return -ENOMEM;
+
/* Record the position of the start of the request so that
* should we detect the updated seqno part-way through the
* GPU processing the request, we never over-estimate the
@@ -2137,13 +2091,17 @@ int __i915_add_request(struct intel_ring_buffer *ring,
request_ring_position = intel_ring_get_tail(ring);
ret = ring->add_request(ring);
- if (ret)
+ if (ret) {
+ kfree(request);
return ret;
+ }
request->seqno = intel_ring_get_seqno(ring);
request->ring = ring;
request->head = request_start;
request->tail = request_ring_position;
+ request->ctx = ring->last_context;
+ request->batch_obj = obj;
/* Whilst this request exists, batch_obj will be on the
* active_list, and so will hold the active reference. Only when this
@@ -2151,12 +2109,7 @@ int __i915_add_request(struct intel_ring_buffer *ring,
* inactive_list and lose its active reference. Hence we do not need
* to explicitly hold another reference here.
*/
- request->batch_obj = obj;
- /* Hold a reference to the current context so that we can inspect
- * it later in case a hangcheck error event fires.
- */
- request->ctx = ring->last_context;
if (request->ctx)
i915_gem_context_reference(request->ctx);
@@ -2176,14 +2129,12 @@ int __i915_add_request(struct intel_ring_buffer *ring,
}
trace_i915_gem_request_add(ring, request->seqno);
- ring->outstanding_lazy_seqno = 0;
- ring->preallocated_lazy_request = NULL;
+ ring->outstanding_lazy_request = 0;
if (!dev_priv->ums.mm_suspended) {
i915_queue_hangcheck(ring->dev);
if (was_empty) {
- cancel_delayed_work_sync(&dev_priv->mm.idle_work);
queue_delayed_work(dev_priv->wq,
&dev_priv->mm.retire_work,
round_jiffies_up_relative(HZ));
@@ -2205,8 +2156,10 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
return;
spin_lock(&file_priv->mm.lock);
- list_del(&request->client_list);
- request->file_priv = NULL;
+ if (request->file_priv) {
+ list_del(&request->client_list);
+ request->file_priv = NULL;
+ }
spin_unlock(&file_priv->mm.lock);
}
@@ -2271,21 +2224,6 @@ static bool i915_request_guilty(struct drm_i915_gem_request *request,
return false;
}
-static bool i915_context_is_banned(const struct i915_ctx_hang_stats *hs)
-{
- const unsigned long elapsed = get_seconds() - hs->guilty_ts;
-
- if (hs->banned)
- return true;
-
- if (elapsed <= DRM_I915_CTX_BAN_PERIOD) {
- DRM_ERROR("context hanging too fast, declaring banned!\n");
- return true;
- }
-
- return false;
-}
-
static void i915_set_reset_status(struct intel_ring_buffer *ring,
struct drm_i915_gem_request *request,
u32 acthd)
@@ -2322,13 +2260,10 @@ static void i915_set_reset_status(struct intel_ring_buffer *ring,
hs = &request->file_priv->hang_stats;
if (hs) {
- if (guilty) {
- hs->banned = i915_context_is_banned(hs);
+ if (guilty)
hs->batch_active++;
- hs->guilty_ts = get_seconds();
- } else {
+ else
hs->batch_pending++;
- }
}
}
@@ -2406,8 +2341,6 @@ void i915_gem_reset(struct drm_device *dev)
for_each_ring(ring, dev_priv, i)
i915_gem_reset_ring_lists(dev_priv, ring);
- i915_gem_cleanup_ringbuffer(dev);
-
i915_gem_restore_fences(dev);
}
@@ -2472,53 +2405,57 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
WARN_ON(i915_verify_lists(ring->dev));
}
-bool
+void
i915_gem_retire_requests(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
- bool idle = true;
int i;
- for_each_ring(ring, dev_priv, i) {
+ for_each_ring(ring, dev_priv, i)
i915_gem_retire_requests_ring(ring);
- idle &= list_empty(&ring->request_list);
- }
-
- if (idle)
- mod_delayed_work(dev_priv->wq,
- &dev_priv->mm.idle_work,
- msecs_to_jiffies(100));
-
- return idle;
}
static void
i915_gem_retire_work_handler(struct work_struct *work)
{
- struct drm_i915_private *dev_priv =
- container_of(work, typeof(*dev_priv), mm.retire_work.work);
- struct drm_device *dev = dev_priv->dev;
+ drm_i915_private_t *dev_priv;
+ struct drm_device *dev;
+ struct intel_ring_buffer *ring;
bool idle;
+ int i;
+
+ dev_priv = container_of(work, drm_i915_private_t,
+ mm.retire_work.work);
+ dev = dev_priv->dev;
/* Come back later if the device is busy... */
- idle = false;
- if (mutex_trylock(&dev->struct_mutex)) {
- idle = i915_gem_retire_requests(dev);
- mutex_unlock(&dev->struct_mutex);
- }
- if (!idle)
+ if (!mutex_trylock(&dev->struct_mutex)) {
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work,
round_jiffies_up_relative(HZ));
-}
+ return;
+ }
-static void
-i915_gem_idle_work_handler(struct work_struct *work)
-{
- struct drm_i915_private *dev_priv =
- container_of(work, typeof(*dev_priv), mm.idle_work.work);
+ i915_gem_retire_requests(dev);
+
+ /* Send a periodic flush down the ring so we don't hold onto GEM
+ * objects indefinitely.
+ */
+ idle = true;
+ for_each_ring(ring, dev_priv, i) {
+ if (ring->gpu_caches_dirty)
+ i915_add_request(ring, NULL);
+
+ idle &= list_empty(&ring->request_list);
+ }
+
+ if (!dev_priv->ums.mm_suspended && !idle)
+ queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work,
+ round_jiffies_up_relative(HZ));
+ if (idle)
+ intel_mark_idle(dev);
- intel_mark_idle(dev_priv->dev);
+ mutex_unlock(&dev->struct_mutex);
}
/**
@@ -2616,7 +2553,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
mutex_unlock(&dev->struct_mutex);
- ret = __wait_seqno(ring, seqno, reset_counter, true, timeout, file->driver_priv);
+ ret = __wait_seqno(ring, seqno, reset_counter, true, timeout);
if (timeout)
args->timeout_ns = timespec_to_ns(timeout);
return ret;
@@ -2663,7 +2600,6 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
if (ret)
return ret;
- trace_i915_gem_ring_sync_to(from, to, seqno);
ret = to->sync_to(to, from, seqno);
if (!ret)
/* We use last_read_seqno because sync_to()
@@ -2705,17 +2641,11 @@ int i915_vma_unbind(struct i915_vma *vma)
drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
int ret;
- /* For now we only ever use 1 vma per object */
- WARN_ON(!list_is_singular(&obj->vma_list));
-
if (list_empty(&vma->vma_link))
return 0;
- if (!drm_mm_node_allocated(&vma->node)) {
- i915_gem_vma_destroy(vma);
-
- return 0;
- }
+ if (!drm_mm_node_allocated(&vma->node))
+ goto destroy;
if (obj->pin_count)
return -EBUSY;
@@ -2755,10 +2685,13 @@ int i915_vma_unbind(struct i915_vma *vma)
drm_mm_remove_node(&vma->node);
+destroy:
i915_gem_vma_destroy(vma);
/* Since the unbound list is global, only move to that list if
- * no more VMAs exist. */
+ * no more VMAs exist.
+ * NB: Until we have real VMAs there will only ever be one */
+ WARN_ON(!list_empty(&obj->vma_list));
if (list_empty(&obj->vma_list))
list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list);
@@ -2954,7 +2887,6 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg,
obj->stride, obj->tiling_mode);
switch (INTEL_INFO(dev)->gen) {
- case 8:
case 7:
case 6:
case 5:
@@ -3457,7 +3389,8 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
/* And bump the LRU for this access */
if (i915_gem_object_is_inactive(obj)) {
- struct i915_vma *vma = i915_gem_obj_to_ggtt(obj);
+ struct i915_vma *vma = i915_gem_obj_to_vma(obj,
+ &dev_priv->gtt.base);
if (vma)
list_move_tail(&vma->mm_list,
&dev_priv->gtt.base.inactive_list);
@@ -3828,7 +3761,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
if (seqno == 0)
return 0;
- ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, NULL);
+ ret = __wait_seqno(ring, seqno, reset_counter, true, NULL);
if (ret == 0)
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
@@ -3932,11 +3865,6 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
goto out;
}
- if (obj->user_pin_count == ULONG_MAX) {
- ret = -EBUSY;
- goto out;
- }
-
if (obj->user_pin_count == 0) {
ret = i915_gem_obj_ggtt_pin(obj, args->alignment, true, false);
if (ret)
@@ -4087,6 +4015,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
{
INIT_LIST_HEAD(&obj->global_list);
INIT_LIST_HEAD(&obj->ring_list);
+ INIT_LIST_HEAD(&obj->exec_list);
INIT_LIST_HEAD(&obj->obj_exec_link);
INIT_LIST_HEAD(&obj->vma_list);
@@ -4158,6 +4087,13 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
return obj;
}
+int i915_gem_init_object(struct drm_gem_object *obj)
+{
+ BUG();
+
+ return 0;
+}
+
void i915_gem_free_object(struct drm_gem_object *gem_obj)
{
struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
@@ -4211,20 +4147,9 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
i915_gem_object_free(obj);
}
-struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
+struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj,
struct i915_address_space *vm)
{
- struct i915_vma *vma;
- list_for_each_entry(vma, &obj->vma_list, vma_link)
- if (vma->vm == vm)
- return vma;
-
- return NULL;
-}
-
-static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm)
-{
struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL);
if (vma == NULL)
return ERR_PTR(-ENOMEM);
@@ -4244,103 +4169,76 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
return vma;
}
-struct i915_vma *
-i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm)
-{
- struct i915_vma *vma;
-
- vma = i915_gem_obj_to_vma(obj, vm);
- if (!vma)
- vma = __i915_gem_vma_create(obj, vm);
-
- return vma;
-}
-
void i915_gem_vma_destroy(struct i915_vma *vma)
{
WARN_ON(vma->node.allocated);
-
- /* Keep the vma as a placeholder in the execbuffer reservation lists */
- if (!list_empty(&vma->exec_list))
- return;
-
list_del(&vma->vma_link);
-
kfree(vma);
}
int
-i915_gem_suspend(struct drm_device *dev)
+i915_gem_idle(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- int ret = 0;
+ int ret;
- mutex_lock(&dev->struct_mutex);
- if (dev_priv->ums.mm_suspended)
- goto err;
+ if (dev_priv->ums.mm_suspended) {
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+ }
ret = i915_gpu_idle(dev);
- if (ret)
- goto err;
-
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
i915_gem_retire_requests(dev);
/* Under UMS, be paranoid and evict. */
if (!drm_core_check_feature(dev, DRIVER_MODESET))
i915_gem_evict_everything(dev);
+ del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
+
i915_kernel_lost_context(dev);
i915_gem_cleanup_ringbuffer(dev);
- /* Hack! Don't let anybody do execbuf while we don't control the chip.
- * We need to replace this with a semaphore, or something.
- * And not confound ums.mm_suspended!
- */
- dev_priv->ums.mm_suspended = !drm_core_check_feature(dev,
- DRIVER_MODESET);
- mutex_unlock(&dev->struct_mutex);
-
- del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
+ /* Cancel the retire work handler, which should be idle now. */
cancel_delayed_work_sync(&dev_priv->mm.retire_work);
- cancel_delayed_work_sync(&dev_priv->mm.idle_work);
return 0;
-
-err:
- mutex_unlock(&dev->struct_mutex);
- return ret;
}
-int i915_gem_l3_remap(struct intel_ring_buffer *ring, int slice)
+void i915_gem_l3_remap(struct drm_device *dev)
{
- struct drm_device *dev = ring->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 reg_base = GEN7_L3LOG_BASE + (slice * 0x200);
- u32 *remap_info = dev_priv->l3_parity.remap_info[slice];
- int i, ret;
+ u32 misccpctl;
+ int i;
- if (!HAS_L3_DPF(dev) || !remap_info)
- return 0;
+ if (!HAS_L3_GPU_CACHE(dev))
+ return;
- ret = intel_ring_begin(ring, GEN7_L3LOG_SIZE / 4 * 3);
- if (ret)
- return ret;
+ if (!dev_priv->l3_parity.remap_info)
+ return;
+
+ misccpctl = I915_READ(GEN7_MISCCPCTL);
+ I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+ POSTING_READ(GEN7_MISCCPCTL);
- /*
- * Note: We do not worry about the concurrent register cacheline hang
- * here because no other code should access these registers other than
- * at initialization time.
- */
for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) {
- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(ring, reg_base + i);
- intel_ring_emit(ring, remap_info[i/4]);
+ u32 remap = I915_READ(GEN7_L3LOG_BASE + i);
+ if (remap && remap != dev_priv->l3_parity.remap_info[i/4])
+ DRM_DEBUG("0x%x was already programmed to %x\n",
+ GEN7_L3LOG_BASE + i, remap);
+ if (remap && !dev_priv->l3_parity.remap_info[i/4])
+ DRM_DEBUG_DRIVER("Clearing remapped register\n");
+ I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->l3_parity.remap_info[i/4]);
}
- intel_ring_advance(ring);
+ /* Make sure all the writes land before disabling dop clock gating */
+ POSTING_READ(GEN7_L3LOG_BASE);
- return ret;
+ I915_WRITE(GEN7_MISCCPCTL, misccpctl);
}
void i915_gem_init_swizzling(struct drm_device *dev)
@@ -4362,8 +4260,6 @@ void i915_gem_init_swizzling(struct drm_device *dev)
I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB));
else if (IS_GEN7(dev))
I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB));
- else if (IS_GEN8(dev))
- I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_BDW));
else
BUG();
}
@@ -4434,7 +4330,7 @@ int
i915_gem_init_hw(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- int ret, i;
+ int ret;
if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
return -EIO;
@@ -4442,25 +4338,20 @@ i915_gem_init_hw(struct drm_device *dev)
if (dev_priv->ellc_size)
I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf));
- if (IS_HASWELL(dev))
- I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev) ?
- LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
-
if (HAS_PCH_NOP(dev)) {
u32 temp = I915_READ(GEN7_MSG_CTL);
temp &= ~(WAIT_FOR_PCH_FLR_ACK | WAIT_FOR_PCH_RESET_ACK);
I915_WRITE(GEN7_MSG_CTL, temp);
}
+ i915_gem_l3_remap(dev);
+
i915_gem_init_swizzling(dev);
ret = i915_gem_init_rings(dev);
if (ret)
return ret;
- for (i = 0; i < NUM_L3_SLICES(dev); i++)
- i915_gem_l3_remap(&dev_priv->ring[RCS], i);
-
/*
* XXX: There was some w/a described somewhere suggesting loading
* contexts before PPGTT.
@@ -4563,12 +4454,26 @@ int
i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+
if (drm_core_check_feature(dev, DRIVER_MODESET))
return 0;
drm_irq_uninstall(dev);
- return i915_gem_suspend(dev);
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_idle(dev);
+
+ /* Hack! Don't let anybody do execbuf while we don't control the chip.
+ * We need to replace this with a semaphore, or something.
+ * And not confound ums.mm_suspended!
+ */
+ if (ret != 0)
+ dev_priv->ums.mm_suspended = 1;
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
}
void
@@ -4579,9 +4484,11 @@ i915_gem_lastclose(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
- ret = i915_gem_suspend(dev);
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_idle(dev);
if (ret)
DRM_ERROR("failed to idle hardware: %d\n", ret);
+ mutex_unlock(&dev->struct_mutex);
}
static void
@@ -4616,7 +4523,6 @@ i915_gem_load(struct drm_device *dev)
INIT_LIST_HEAD(&dev_priv->vm_list);
i915_init_vm(dev_priv, &dev_priv->gtt.base);
- INIT_LIST_HEAD(&dev_priv->context_list);
INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
INIT_LIST_HEAD(&dev_priv->mm.bound_list);
INIT_LIST_HEAD(&dev_priv->mm.fence_list);
@@ -4626,8 +4532,6 @@ i915_gem_load(struct drm_device *dev)
INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
i915_gem_retire_work_handler);
- INIT_DELAYED_WORK(&dev_priv->mm.idle_work,
- i915_gem_idle_work_handler);
init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
/* On GEN3 we really need to make sure the ARB C3 LP bit is set */
@@ -4678,7 +4582,7 @@ static int i915_gem_init_phys_object(struct drm_device *dev,
if (dev_priv->mm.phys_objs[id - 1] || !size)
return 0;
- phys_obj = kzalloc(sizeof(*phys_obj), GFP_KERNEL);
+ phys_obj = kzalloc(sizeof(struct drm_i915_gem_phys_object), GFP_KERNEL);
if (!phys_obj)
return -ENOMEM;
@@ -4852,8 +4756,6 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
- cancel_delayed_work_sync(&file_priv->mm.idle_work);
-
/* Clean up our request list when the client is going away, so that
* later retire_requests won't dereference our soon-to-be-gone
* file_priv.
@@ -4871,38 +4773,6 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
spin_unlock(&file_priv->mm.lock);
}
-static void
-i915_gem_file_idle_work_handler(struct work_struct *work)
-{
- struct drm_i915_file_private *file_priv =
- container_of(work, typeof(*file_priv), mm.idle_work.work);
-
- atomic_set(&file_priv->rps_wait_boost, false);
-}
-
-int i915_gem_open(struct drm_device *dev, struct drm_file *file)
-{
- struct drm_i915_file_private *file_priv;
-
- DRM_DEBUG_DRIVER("\n");
-
- file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
- if (!file_priv)
- return -ENOMEM;
-
- file->driver_priv = file_priv;
- file_priv->dev_priv = dev->dev_private;
-
- spin_lock_init(&file_priv->mm.lock);
- INIT_LIST_HEAD(&file_priv->mm.request_list);
- INIT_DELAYED_WORK(&file_priv->mm.idle_work,
- i915_gem_file_idle_work_handler);
-
- idr_init(&file_priv->context_idr);
-
- return 0;
-}
-
static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
{
if (!mutex_is_locked(mutex))
@@ -4953,7 +4823,6 @@ i915_gem_inactive_count(struct shrinker *shrinker, struct shrink_control *sc)
if (unlock)
mutex_unlock(&dev->struct_mutex);
-
return count;
}
@@ -4990,10 +4859,11 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o)
{
- struct i915_vma *vma;
+ struct drm_i915_private *dev_priv = o->base.dev->dev_private;
+ struct i915_address_space *vm;
- list_for_each_entry(vma, &o->vma_list, vma_link)
- if (drm_mm_node_allocated(&vma->node))
+ list_for_each_entry(vm, &dev_priv->vm_list, global_link)
+ if (i915_gem_obj_bound(o, vm))
return true;
return false;
@@ -5025,6 +4895,7 @@ i915_gem_inactive_scan(struct shrinker *shrinker, struct shrink_control *sc)
struct drm_i915_private,
mm.inactive_shrinker);
struct drm_device *dev = dev_priv->dev;
+ int nr_to_scan = sc->nr_to_scan;
unsigned long freed;
bool unlock = true;
@@ -5038,30 +4909,38 @@ i915_gem_inactive_scan(struct shrinker *shrinker, struct shrink_control *sc)
unlock = false;
}
- freed = i915_gem_purge(dev_priv, sc->nr_to_scan);
- if (freed < sc->nr_to_scan)
- freed += __i915_gem_shrink(dev_priv,
- sc->nr_to_scan - freed,
- false);
- if (freed < sc->nr_to_scan)
+ freed = i915_gem_purge(dev_priv, nr_to_scan);
+ if (freed < nr_to_scan)
+ freed += __i915_gem_shrink(dev_priv, nr_to_scan,
+ false);
+ if (freed < nr_to_scan)
freed += i915_gem_shrink_all(dev_priv);
if (unlock)
mutex_unlock(&dev->struct_mutex);
-
return freed;
}
-struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj)
+struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm)
{
struct i915_vma *vma;
+ list_for_each_entry(vma, &obj->vma_list, vma_link)
+ if (vma->vm == vm)
+ return vma;
- if (WARN_ON(list_empty(&obj->vma_list)))
- return NULL;
+ return NULL;
+}
- vma = list_first_entry(&obj->vma_list, typeof(*vma), vma_link);
- if (WARN_ON(vma->vm != obj_to_ggtt(obj)))
- return NULL;
+struct i915_vma *
+i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm)
+{
+ struct i915_vma *vma;
+
+ vma = i915_gem_obj_to_vma(obj, vm);
+ if (!vma)
+ vma = i915_gem_vma_create(obj, vm);
return vma;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 72a3df3..403309c 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -73,7 +73,7 @@
*
* There are two confusing terms used above:
* The "current context" means the context which is currently running on the
- * GPU. The GPU has loaded its state already and has stored away the gtt
+ * GPU. The GPU has loaded it's state already and has stored away the gtt
* offset of the BO. The GPU is not actively referencing the data at this
* offset, but it will on the next context switch. The only way to avoid this
* is to do a GPU reset.
@@ -117,9 +117,6 @@ static int get_context_size(struct drm_device *dev)
else
ret = GEN7_CXT_TOTAL_SIZE(reg) * 64;
break;
- case 8:
- ret = GEN8_CXT_TOTAL_SIZE;
- break;
default:
BUG();
}
@@ -132,7 +129,6 @@ void i915_gem_context_free(struct kref *ctx_ref)
struct i915_hw_context *ctx = container_of(ctx_ref,
typeof(*ctx), ref);
- list_del(&ctx->link);
drm_gem_object_unreference(&ctx->obj->base);
kfree(ctx);
}
@@ -151,7 +147,6 @@ create_hw_context(struct drm_device *dev,
kref_init(&ctx->ref);
ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
- INIT_LIST_HEAD(&ctx->link);
if (ctx->obj == NULL) {
kfree(ctx);
DRM_DEBUG_DRIVER("Context object allocated failed\n");
@@ -171,7 +166,6 @@ create_hw_context(struct drm_device *dev,
* assertion in the context switch code.
*/
ctx->ring = &dev_priv->ring[RCS];
- list_add_tail(&ctx->link, &dev_priv->context_list);
/* Default context will never have a file_priv */
if (file_priv == NULL)
@@ -184,10 +178,6 @@ create_hw_context(struct drm_device *dev,
ctx->file_priv = file_priv;
ctx->id = ret;
- /* NB: Mark all slices as needing a remap so that when the context first
- * loads it will restore whatever remap state already exists. If there
- * is no remap info, it will be a NOP. */
- ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;
return ctx;
@@ -223,6 +213,7 @@ static int create_default_context(struct drm_i915_private *dev_priv)
* may not be available. To avoid this we always pin the
* default context.
*/
+ dev_priv->ring[RCS].default_context = ctx;
ret = i915_gem_obj_ggtt_pin(ctx->obj, CONTEXT_ALIGN, false, false);
if (ret) {
DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
@@ -235,8 +226,6 @@ static int create_default_context(struct drm_i915_private *dev_priv)
goto err_unpin;
}
- dev_priv->ring[RCS].default_context = ctx;
-
DRM_DEBUG_DRIVER("Default HW context loaded\n");
return 0;
@@ -292,24 +281,16 @@ void i915_gem_context_fini(struct drm_device *dev)
* other code, leading to spurious errors. */
intel_gpu_reset(dev);
+ i915_gem_object_unpin(dctx->obj);
+
/* When default context is created and switched to, base object refcount
* will be 2 (+1 from object creation and +1 from do_switch()).
* i915_gem_context_fini() will be called after gpu_idle() has switched
* to default context. So we need to unreference the base object once
* to offset the do_switch part, so that i915_gem_context_unreference()
* can then free the base object correctly. */
- WARN_ON(!dev_priv->ring[RCS].last_context);
- if (dev_priv->ring[RCS].last_context == dctx) {
- /* Fake switch to NULL context */
- WARN_ON(dctx->obj->active);
- i915_gem_object_unpin(dctx->obj);
- i915_gem_context_unreference(dctx);
- }
-
- i915_gem_object_unpin(dctx->obj);
+ drm_gem_object_unreference(&dctx->obj->base);
i915_gem_context_unreference(dctx);
- dev_priv->ring[RCS].default_context = NULL;
- dev_priv->ring[RCS].last_context = NULL;
}
static int context_idr_cleanup(int id, void *p, void *data)
@@ -412,11 +393,11 @@ static int do_switch(struct i915_hw_context *to)
struct intel_ring_buffer *ring = to->ring;
struct i915_hw_context *from = ring->last_context;
u32 hw_flags = 0;
- int ret, i;
+ int ret;
BUG_ON(from != NULL && from->obj != NULL && from->obj->pin_count == 0);
- if (from == to && !to->remap_slice)
+ if (from == to)
return 0;
ret = i915_gem_obj_ggtt_pin(to->obj, CONTEXT_ALIGN, false, false);
@@ -439,6 +420,8 @@ static int do_switch(struct i915_hw_context *to)
if (!to->is_initialized || is_default_context(to))
hw_flags |= MI_RESTORE_INHIBIT;
+ else if (WARN_ON_ONCE(from == to)) /* not yet expected */
+ hw_flags |= MI_FORCE_RESTORE;
ret = mi_set_context(ring, to, hw_flags);
if (ret) {
@@ -446,18 +429,6 @@ static int do_switch(struct i915_hw_context *to)
return ret;
}
- for (i = 0; i < MAX_L3_SLICES; i++) {
- if (!(to->remap_slice & (1<<i)))
- continue;
-
- ret = i915_gem_l3_remap(ring, i);
- /* If it failed, try again next round */
- if (ret)
- DRM_DEBUG_DRIVER("L3 remapping failed\n");
- else
- to->remap_slice &= ~(1<<i);
- }
-
/* The backing object for the context is done after switching to the
* *next* context. Therefore we cannot retire the previous context until
* the next context has already started running. In fact, the below code
@@ -465,8 +436,11 @@ static int do_switch(struct i915_hw_context *to)
* MI_SET_CONTEXT instead of when the next seqno has completed.
*/
if (from != NULL) {
+ struct drm_i915_private *dev_priv = from->obj->base.dev->dev_private;
+ struct i915_address_space *ggtt = &dev_priv->gtt.base;
from->obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
- i915_vma_move_to_active(i915_gem_obj_to_ggtt(from->obj), ring);
+ list_move_tail(&i915_gem_obj_to_vma(from->obj, ggtt)->mm_list, &ggtt->active_list);
+ i915_gem_object_move_to_active(from->obj, ring);
/* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
* whole damn pipeline, we don't need to explicitly mark the
* object dirty. The only exception is that the context must be
@@ -477,7 +451,17 @@ static int do_switch(struct i915_hw_context *to)
from->obj->dirty = 1;
BUG_ON(from->obj->ring != ring);
- /* obj is kept alive until the next request by its active ref */
+ ret = i915_add_request(ring, NULL);
+ if (ret) {
+ /* Too late, we've already scheduled a context switch.
+ * Try to undo the change so that the hw state is
+ * consistent with out tracking. In case of emergency,
+ * scream.
+ */
+ WARN_ON(mi_set_context(ring, from, MI_RESTORE_INHIBIT));
+ return ret;
+ }
+
i915_gem_object_unpin(from->obj);
i915_gem_context_unreference(from);
}
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 9bb533e..7d5752f 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -125,15 +125,13 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
ret = i915_gem_object_get_pages(obj);
if (ret)
- goto err;
-
- i915_gem_object_pin_pages(obj);
+ goto error;
ret = -ENOMEM;
pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages));
if (pages == NULL)
- goto err_unpin;
+ goto error;
i = 0;
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0)
@@ -143,16 +141,15 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
drm_free_large(pages);
if (!obj->dma_buf_vmapping)
- goto err_unpin;
+ goto error;
obj->vmapping_count = 1;
+ i915_gem_object_pin_pages(obj);
out_unlock:
mutex_unlock(&dev->struct_mutex);
return obj->dma_buf_vmapping;
-err_unpin:
- i915_gem_object_unpin_pages(obj);
-err:
+error:
mutex_unlock(&dev->struct_mutex);
return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index b737653..91b7001 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -37,9 +37,6 @@ mark_free(struct i915_vma *vma, struct list_head *unwind)
if (vma->obj->pin_count)
return false;
- if (WARN_ON(!list_empty(&vma->exec_list)))
- return false;
-
list_add(&vma->exec_list, unwind);
return drm_mm_scan_add_block(&vma->node);
}
@@ -116,7 +113,7 @@ none:
}
/* We expect the caller to unpin, evict all and try again, or give up.
- * So calling i915_gem_evict_vm() is unnecessary.
+ * So calling i915_gem_evict_everything() is unnecessary.
*/
return -ENOSPC;
@@ -155,48 +152,12 @@ found:
return ret;
}
-/**
- * i915_gem_evict_vm - Try to free up VM space
- *
- * @vm: Address space to evict from
- * @do_idle: Boolean directing whether to idle first.
- *
- * VM eviction is about freeing up virtual address space. If one wants fine
- * grained eviction, they should see evict something for more details. In terms
- * of freeing up actual system memory, this function may not accomplish the
- * desired result. An object may be shared in multiple address space, and this
- * function will not assert those objects be freed.
- *
- * Using do_idle will result in a more complete eviction because it retires, and
- * inactivates current BOs.
- */
-int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
-{
- struct i915_vma *vma, *next;
- int ret;
-
- trace_i915_gem_evict_vm(vm);
-
- if (do_idle) {
- ret = i915_gpu_idle(vm->dev);
- if (ret)
- return ret;
-
- i915_gem_retire_requests(vm->dev);
- }
-
- list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
- if (vma->obj->pin_count == 0)
- WARN_ON(i915_vma_unbind(vma));
-
- return 0;
-}
-
int
i915_gem_evict_everything(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct i915_address_space *vm;
+ struct i915_vma *vma, *next;
bool lists_empty = true;
int ret;
@@ -223,8 +184,11 @@ i915_gem_evict_everything(struct drm_device *dev)
i915_gem_retire_requests(dev);
/* Having flushed everything, unbind() should never raise an error */
- list_for_each_entry(vm, &dev_priv->vm_list, global_link)
- WARN_ON(i915_gem_evict_vm(vm, false));
+ list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
+ list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
+ if (vma->obj->pin_count == 0)
+ WARN_ON(i915_vma_unbind(vma));
+ }
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index b7e787f..bf34577 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -33,38 +33,35 @@
#include "intel_drv.h"
#include <linux/dma_remapping.h>
-#define __EXEC_OBJECT_HAS_PIN (1<<31)
-#define __EXEC_OBJECT_HAS_FENCE (1<<30)
-
-struct eb_vmas {
- struct list_head vmas;
+struct eb_objects {
+ struct list_head objects;
int and;
union {
- struct i915_vma *lut[0];
+ struct drm_i915_gem_object *lut[0];
struct hlist_head buckets[0];
};
};
-static struct eb_vmas *
-eb_create(struct drm_i915_gem_execbuffer2 *args, struct i915_address_space *vm)
+static struct eb_objects *
+eb_create(struct drm_i915_gem_execbuffer2 *args)
{
- struct eb_vmas *eb = NULL;
+ struct eb_objects *eb = NULL;
if (args->flags & I915_EXEC_HANDLE_LUT) {
- unsigned size = args->buffer_count;
- size *= sizeof(struct i915_vma *);
- size += sizeof(struct eb_vmas);
+ int size = args->buffer_count;
+ size *= sizeof(struct drm_i915_gem_object *);
+ size += sizeof(struct eb_objects);
eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
}
if (eb == NULL) {
- unsigned size = args->buffer_count;
- unsigned count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
+ int size = args->buffer_count;
+ int count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head));
while (count > 2*size)
count >>= 1;
eb = kzalloc(count*sizeof(struct hlist_head) +
- sizeof(struct eb_vmas),
+ sizeof(struct eb_objects),
GFP_TEMPORARY);
if (eb == NULL)
return eb;
@@ -73,102 +70,64 @@ eb_create(struct drm_i915_gem_execbuffer2 *args, struct i915_address_space *vm)
} else
eb->and = -args->buffer_count;
- INIT_LIST_HEAD(&eb->vmas);
+ INIT_LIST_HEAD(&eb->objects);
return eb;
}
static void
-eb_reset(struct eb_vmas *eb)
+eb_reset(struct eb_objects *eb)
{
if (eb->and >= 0)
memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
}
static int
-eb_lookup_vmas(struct eb_vmas *eb,
- struct drm_i915_gem_exec_object2 *exec,
- const struct drm_i915_gem_execbuffer2 *args,
- struct i915_address_space *vm,
- struct drm_file *file)
+eb_lookup_objects(struct eb_objects *eb,
+ struct drm_i915_gem_exec_object2 *exec,
+ const struct drm_i915_gem_execbuffer2 *args,
+ struct drm_file *file)
{
- struct drm_i915_gem_object *obj;
- struct list_head objects;
- int i, ret = 0;
+ int i;
- INIT_LIST_HEAD(&objects);
spin_lock(&file->table_lock);
- /* Grab a reference to the object and release the lock so we can lookup
- * or create the VMA without using GFP_ATOMIC */
for (i = 0; i < args->buffer_count; i++) {
+ struct drm_i915_gem_object *obj;
+
obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle));
if (obj == NULL) {
spin_unlock(&file->table_lock);
DRM_DEBUG("Invalid object handle %d at index %d\n",
exec[i].handle, i);
- ret = -ENOENT;
- goto out;
+ return -ENOENT;
}
- if (!list_empty(&obj->obj_exec_link)) {
+ if (!list_empty(&obj->exec_list)) {
spin_unlock(&file->table_lock);
DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
obj, exec[i].handle, i);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
drm_gem_object_reference(&obj->base);
- list_add_tail(&obj->obj_exec_link, &objects);
- }
- spin_unlock(&file->table_lock);
-
- i = 0;
- list_for_each_entry(obj, &objects, obj_exec_link) {
- struct i915_vma *vma;
+ list_add_tail(&obj->exec_list, &eb->objects);
- /*
- * NOTE: We can leak any vmas created here when something fails
- * later on. But that's no issue since vma_unbind can deal with
- * vmas which are not actually bound. And since only
- * lookup_or_create exists as an interface to get at the vma
- * from the (obj, vm) we don't run the risk of creating
- * duplicated vmas for the same vm.
- */
- vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
- if (IS_ERR(vma)) {
- DRM_DEBUG("Failed to lookup VMA\n");
- ret = PTR_ERR(vma);
- goto out;
- }
-
- list_add_tail(&vma->exec_list, &eb->vmas);
-
- vma->exec_entry = &exec[i];
+ obj->exec_entry = &exec[i];
if (eb->and < 0) {
- eb->lut[i] = vma;
+ eb->lut[i] = obj;
} else {
uint32_t handle = args->flags & I915_EXEC_HANDLE_LUT ? i : exec[i].handle;
- vma->exec_handle = handle;
- hlist_add_head(&vma->exec_node,
+ obj->exec_handle = handle;
+ hlist_add_head(&obj->exec_node,
&eb->buckets[handle & eb->and]);
}
- ++i;
}
+ spin_unlock(&file->table_lock);
-
-out:
- while (!list_empty(&objects)) {
- obj = list_first_entry(&objects,
- struct drm_i915_gem_object,
- obj_exec_link);
- list_del_init(&obj->obj_exec_link);
- if (ret)
- drm_gem_object_unreference(&obj->base);
- }
- return ret;
+ return 0;
}
-static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle)
+static struct drm_i915_gem_object *
+eb_get_object(struct eb_objects *eb, unsigned long handle)
{
if (eb->and < 0) {
if (handle >= -eb->and)
@@ -180,55 +139,34 @@ static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle)
head = &eb->buckets[handle & eb->and];
hlist_for_each(node, head) {
- struct i915_vma *vma;
+ struct drm_i915_gem_object *obj;
- vma = hlist_entry(node, struct i915_vma, exec_node);
- if (vma->exec_handle == handle)
- return vma;
+ obj = hlist_entry(node, struct drm_i915_gem_object, exec_node);
+ if (obj->exec_handle == handle)
+ return obj;
}
return NULL;
}
}
static void
-i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
+eb_destroy(struct eb_objects *eb)
{
- struct drm_i915_gem_exec_object2 *entry;
- struct drm_i915_gem_object *obj = vma->obj;
-
- if (!drm_mm_node_allocated(&vma->node))
- return;
-
- entry = vma->exec_entry;
-
- if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
- i915_gem_object_unpin_fence(obj);
-
- if (entry->flags & __EXEC_OBJECT_HAS_PIN)
- i915_gem_object_unpin(obj);
-
- entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
-}
-
-static void eb_destroy(struct eb_vmas *eb)
-{
- while (!list_empty(&eb->vmas)) {
- struct i915_vma *vma;
+ while (!list_empty(&eb->objects)) {
+ struct drm_i915_gem_object *obj;
- vma = list_first_entry(&eb->vmas,
- struct i915_vma,
+ obj = list_first_entry(&eb->objects,
+ struct drm_i915_gem_object,
exec_list);
- list_del_init(&vma->exec_list);
- i915_gem_execbuffer_unreserve_vma(vma);
- drm_gem_object_unreference(&vma->obj->base);
+ list_del_init(&obj->exec_list);
+ drm_gem_object_unreference(&obj->base);
}
kfree(eb);
}
static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
{
- return (HAS_LLC(obj->base.dev) ||
- obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
+ return (obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
!obj->map_and_fenceable ||
obj->cache_level != I915_CACHE_NONE);
}
@@ -237,31 +175,17 @@ static int
relocate_entry_cpu(struct drm_i915_gem_object *obj,
struct drm_i915_gem_relocation_entry *reloc)
{
- struct drm_device *dev = obj->base.dev;
uint32_t page_offset = offset_in_page(reloc->offset);
char *vaddr;
int ret = -EINVAL;
- ret = i915_gem_object_set_to_cpu_domain(obj, true);
+ ret = i915_gem_object_set_to_cpu_domain(obj, 1);
if (ret)
return ret;
vaddr = kmap_atomic(i915_gem_object_get_page(obj,
reloc->offset >> PAGE_SHIFT));
*(uint32_t *)(vaddr + page_offset) = reloc->delta;
-
- if (INTEL_INFO(dev)->gen >= 8) {
- page_offset = offset_in_page(page_offset + sizeof(uint32_t));
-
- if (page_offset == 0) {
- kunmap_atomic(vaddr);
- vaddr = kmap_atomic(i915_gem_object_get_page(obj,
- (reloc->offset + sizeof(uint32_t)) >> PAGE_SHIFT));
- }
-
- *(uint32_t *)(vaddr + page_offset) = 0;
- }
-
kunmap_atomic(vaddr);
return 0;
@@ -292,21 +216,6 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
reloc_entry = (uint32_t __iomem *)
(reloc_page + offset_in_page(reloc->offset));
iowrite32(reloc->delta, reloc_entry);
-
- if (INTEL_INFO(dev)->gen >= 8) {
- reloc_entry += 1;
-
- if (offset_in_page(reloc->offset + sizeof(uint32_t)) == 0) {
- io_mapping_unmap_atomic(reloc_page);
- reloc_page = io_mapping_map_atomic_wc(
- dev_priv->gtt.mappable,
- reloc->offset + sizeof(uint32_t));
- reloc_entry = reloc_page;
- }
-
- iowrite32(0, reloc_entry);
- }
-
io_mapping_unmap_atomic(reloc_page);
return 0;
@@ -314,24 +223,22 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
static int
i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
- struct eb_vmas *eb,
+ struct eb_objects *eb,
struct drm_i915_gem_relocation_entry *reloc,
struct i915_address_space *vm)
{
struct drm_device *dev = obj->base.dev;
struct drm_gem_object *target_obj;
struct drm_i915_gem_object *target_i915_obj;
- struct i915_vma *target_vma;
uint32_t target_offset;
int ret = -EINVAL;
/* we've already hold a reference to all valid objects */
- target_vma = eb_get_vma(eb, reloc->target_handle);
- if (unlikely(target_vma == NULL))
+ target_obj = &eb_get_object(eb, reloc->target_handle)->base;
+ if (unlikely(target_obj == NULL))
return -ENOENT;
- target_i915_obj = target_vma->obj;
- target_obj = &target_vma->obj->base;
+ target_i915_obj = to_intel_bo(target_obj);
target_offset = i915_gem_obj_ggtt_offset(target_i915_obj);
/* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
@@ -377,8 +284,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
return 0;
/* Check that the relocation address is valid... */
- if (unlikely(reloc->offset >
- obj->base.size - (INTEL_INFO(dev)->gen >= 8 ? 8 : 4))) {
+ if (unlikely(reloc->offset > obj->base.size - 4)) {
DRM_DEBUG("Relocation beyond object bounds: "
"obj %p target %d offset %d size %d.\n",
obj, reloc->target_handle,
@@ -414,13 +320,14 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
}
static int
-i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
- struct eb_vmas *eb)
+i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
+ struct eb_objects *eb,
+ struct i915_address_space *vm)
{
#define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry))
struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)];
struct drm_i915_gem_relocation_entry __user *user_relocs;
- struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
int remain, ret;
user_relocs = to_user_ptr(entry->relocs_ptr);
@@ -439,8 +346,8 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
do {
u64 offset = r->presumed_offset;
- ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r,
- vma->vm);
+ ret = i915_gem_execbuffer_relocate_entry(obj, eb, r,
+ vm);
if (ret)
return ret;
@@ -461,16 +368,17 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
}
static int
-i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
- struct eb_vmas *eb,
- struct drm_i915_gem_relocation_entry *relocs)
+i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
+ struct eb_objects *eb,
+ struct drm_i915_gem_relocation_entry *relocs,
+ struct i915_address_space *vm)
{
- const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
int i, ret;
for (i = 0; i < entry->relocation_count; i++) {
- ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i],
- vma->vm);
+ ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i],
+ vm);
if (ret)
return ret;
}
@@ -479,10 +387,10 @@ i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
}
static int
-i915_gem_execbuffer_relocate(struct eb_vmas *eb,
+i915_gem_execbuffer_relocate(struct eb_objects *eb,
struct i915_address_space *vm)
{
- struct i915_vma *vma;
+ struct drm_i915_gem_object *obj;
int ret = 0;
/* This is the fast path and we cannot handle a pagefault whilst
@@ -493,8 +401,8 @@ i915_gem_execbuffer_relocate(struct eb_vmas *eb,
* lockdep complains vehemently.
*/
pagefault_disable();
- list_for_each_entry(vma, &eb->vmas, exec_list) {
- ret = i915_gem_execbuffer_relocate_vma(vma, eb);
+ list_for_each_entry(obj, &eb->objects, exec_list) {
+ ret = i915_gem_execbuffer_relocate_object(obj, eb, vm);
if (ret)
break;
}
@@ -503,33 +411,35 @@ i915_gem_execbuffer_relocate(struct eb_vmas *eb,
return ret;
}
+#define __EXEC_OBJECT_HAS_PIN (1<<31)
+#define __EXEC_OBJECT_HAS_FENCE (1<<30)
+
static int
-need_reloc_mappable(struct i915_vma *vma)
+need_reloc_mappable(struct drm_i915_gem_object *obj)
{
- struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
- return entry->relocation_count && !use_cpu_reloc(vma->obj) &&
- i915_is_ggtt(vma->vm);
+ struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
+ return entry->relocation_count && !use_cpu_reloc(obj);
}
static int
-i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
- struct intel_ring_buffer *ring,
- bool *need_reloc)
+i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj,
+ struct intel_ring_buffer *ring,
+ struct i915_address_space *vm,
+ bool *need_reloc)
{
- struct drm_i915_private *dev_priv = ring->dev->dev_private;
- struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
bool need_fence, need_mappable;
- struct drm_i915_gem_object *obj = vma->obj;
int ret;
need_fence =
has_fenced_gpu_access &&
entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
obj->tiling_mode != I915_TILING_NONE;
- need_mappable = need_fence || need_reloc_mappable(vma);
+ need_mappable = need_fence || need_reloc_mappable(obj);
- ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, need_mappable,
+ ret = i915_gem_object_pin(obj, vm, entry->alignment, need_mappable,
false);
if (ret)
return ret;
@@ -557,8 +467,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
obj->has_aliasing_ppgtt_mapping = 1;
}
- if (entry->offset != vma->node.start) {
- entry->offset = vma->node.start;
+ if (entry->offset != i915_gem_obj_offset(obj, vm)) {
+ entry->offset = i915_gem_obj_offset(obj, vm);
*need_reloc = true;
}
@@ -574,48 +484,62 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
return 0;
}
+static void
+i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_gem_exec_object2 *entry;
+
+ if (!i915_gem_obj_bound_any(obj))
+ return;
+
+ entry = obj->exec_entry;
+
+ if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
+ i915_gem_object_unpin_fence(obj);
+
+ if (entry->flags & __EXEC_OBJECT_HAS_PIN)
+ i915_gem_object_unpin(obj);
+
+ entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
+}
+
static int
i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
- struct list_head *vmas,
+ struct list_head *objects,
+ struct i915_address_space *vm,
bool *need_relocs)
{
struct drm_i915_gem_object *obj;
- struct i915_vma *vma;
- struct i915_address_space *vm;
- struct list_head ordered_vmas;
+ struct list_head ordered_objects;
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
int retry;
- if (list_empty(vmas))
- return 0;
-
- vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;
-
- INIT_LIST_HEAD(&ordered_vmas);
- while (!list_empty(vmas)) {
+ INIT_LIST_HEAD(&ordered_objects);
+ while (!list_empty(objects)) {
struct drm_i915_gem_exec_object2 *entry;
bool need_fence, need_mappable;
- vma = list_first_entry(vmas, struct i915_vma, exec_list);
- obj = vma->obj;
- entry = vma->exec_entry;
+ obj = list_first_entry(objects,
+ struct drm_i915_gem_object,
+ exec_list);
+ entry = obj->exec_entry;
need_fence =
has_fenced_gpu_access &&
entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
obj->tiling_mode != I915_TILING_NONE;
- need_mappable = need_fence || need_reloc_mappable(vma);
+ need_mappable = need_fence || need_reloc_mappable(obj);
if (need_mappable)
- list_move(&vma->exec_list, &ordered_vmas);
+ list_move(&obj->exec_list, &ordered_objects);
else
- list_move_tail(&vma->exec_list, &ordered_vmas);
+ list_move_tail(&obj->exec_list, &ordered_objects);
obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND;
obj->base.pending_write_domain = 0;
obj->pending_fenced_gpu_access = false;
}
- list_splice(&ordered_vmas, vmas);
+ list_splice(&ordered_objects, objects);
/* Attempt to pin all of the buffers into the GTT.
* This is done in 3 phases:
@@ -634,53 +558,52 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
int ret = 0;
/* Unbind any ill-fitting objects or pin. */
- list_for_each_entry(vma, vmas, exec_list) {
- struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ list_for_each_entry(obj, objects, exec_list) {
+ struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
bool need_fence, need_mappable;
+ u32 obj_offset;
- obj = vma->obj;
-
- if (!drm_mm_node_allocated(&vma->node))
+ if (!i915_gem_obj_bound(obj, vm))
continue;
+ obj_offset = i915_gem_obj_offset(obj, vm);
need_fence =
has_fenced_gpu_access &&
entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
obj->tiling_mode != I915_TILING_NONE;
- need_mappable = need_fence || need_reloc_mappable(vma);
+ need_mappable = need_fence || need_reloc_mappable(obj);
WARN_ON((need_mappable || need_fence) &&
- !i915_is_ggtt(vma->vm));
+ !i915_is_ggtt(vm));
if ((entry->alignment &&
- vma->node.start & (entry->alignment - 1)) ||
+ obj_offset & (entry->alignment - 1)) ||
(need_mappable && !obj->map_and_fenceable))
- ret = i915_vma_unbind(vma);
+ ret = i915_vma_unbind(i915_gem_obj_to_vma(obj, vm));
else
- ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs);
+ ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs);
if (ret)
goto err;
}
/* Bind fresh objects */
- list_for_each_entry(vma, vmas, exec_list) {
- if (drm_mm_node_allocated(&vma->node))
+ list_for_each_entry(obj, objects, exec_list) {
+ if (i915_gem_obj_bound(obj, vm))
continue;
- ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs);
+ ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs);
if (ret)
goto err;
}
-err:
+err: /* Decrement pin count for bound objects */
+ list_for_each_entry(obj, objects, exec_list)
+ i915_gem_execbuffer_unreserve_object(obj);
+
if (ret != -ENOSPC || retry++)
return ret;
- /* Decrement pin count for bound objects */
- list_for_each_entry(vma, vmas, exec_list)
- i915_gem_execbuffer_unreserve_vma(vma);
-
- ret = i915_gem_evict_vm(vm, true);
+ ret = i915_gem_evict_everything(ring->dev);
if (ret)
return ret;
} while (1);
@@ -691,28 +614,24 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
struct drm_i915_gem_execbuffer2 *args,
struct drm_file *file,
struct intel_ring_buffer *ring,
- struct eb_vmas *eb,
- struct drm_i915_gem_exec_object2 *exec)
+ struct eb_objects *eb,
+ struct drm_i915_gem_exec_object2 *exec,
+ struct i915_address_space *vm)
{
struct drm_i915_gem_relocation_entry *reloc;
- struct i915_address_space *vm;
- struct i915_vma *vma;
+ struct drm_i915_gem_object *obj;
bool need_relocs;
int *reloc_offset;
int i, total, ret;
- unsigned count = args->buffer_count;
-
- if (WARN_ON(list_empty(&eb->vmas)))
- return 0;
-
- vm = list_first_entry(&eb->vmas, struct i915_vma, exec_list)->vm;
+ int count = args->buffer_count;
/* We may process another execbuffer during the unlock... */
- while (!list_empty(&eb->vmas)) {
- vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list);
- list_del_init(&vma->exec_list);
- i915_gem_execbuffer_unreserve_vma(vma);
- drm_gem_object_unreference(&vma->obj->base);
+ while (!list_empty(&eb->objects)) {
+ obj = list_first_entry(&eb->objects,
+ struct drm_i915_gem_object,
+ exec_list);
+ list_del_init(&obj->exec_list);
+ drm_gem_object_unreference(&obj->base);
}
mutex_unlock(&dev->struct_mutex);
@@ -776,19 +695,20 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
/* reacquire the objects */
eb_reset(eb);
- ret = eb_lookup_vmas(eb, exec, args, vm, file);
+ ret = eb_lookup_objects(eb, exec, args, file);
if (ret)
goto err;
need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
- ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs);
+ ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs);
if (ret)
goto err;
- list_for_each_entry(vma, &eb->vmas, exec_list) {
- int offset = vma->exec_entry - exec;
- ret = i915_gem_execbuffer_relocate_vma_slow(vma, eb,
- reloc + reloc_offset[offset]);
+ list_for_each_entry(obj, &eb->objects, exec_list) {
+ int offset = obj->exec_entry - exec;
+ ret = i915_gem_execbuffer_relocate_object_slow(obj, eb,
+ reloc + reloc_offset[offset],
+ vm);
if (ret)
goto err;
}
@@ -807,15 +727,14 @@ err:
static int
i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring,
- struct list_head *vmas)
+ struct list_head *objects)
{
- struct i915_vma *vma;
+ struct drm_i915_gem_object *obj;
uint32_t flush_domains = 0;
bool flush_chipset = false;
int ret;
- list_for_each_entry(vma, vmas, exec_list) {
- struct drm_i915_gem_object *obj = vma->obj;
+ list_for_each_entry(obj, objects, exec_list) {
ret = i915_gem_object_sync(obj, ring);
if (ret)
return ret;
@@ -852,8 +771,8 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
int count)
{
int i;
- unsigned relocs_total = 0;
- unsigned relocs_max = UINT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
+ int relocs_total = 0;
+ int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
for (i = 0; i < count; i++) {
char __user *ptr = to_user_ptr(exec[i].relocs_ptr);
@@ -890,13 +809,13 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
}
static void
-i915_gem_execbuffer_move_to_active(struct list_head *vmas,
+i915_gem_execbuffer_move_to_active(struct list_head *objects,
+ struct i915_address_space *vm,
struct intel_ring_buffer *ring)
{
- struct i915_vma *vma;
+ struct drm_i915_gem_object *obj;
- list_for_each_entry(vma, vmas, exec_list) {
- struct drm_i915_gem_object *obj = vma->obj;
+ list_for_each_entry(obj, objects, exec_list) {
u32 old_read = obj->base.read_domains;
u32 old_write = obj->base.write_domain;
@@ -906,7 +825,9 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
obj->base.read_domains = obj->base.pending_read_domains;
obj->fenced_gpu_access = obj->pending_fenced_gpu_access;
- i915_vma_move_to_active(vma, ring);
+ /* FIXME: This lookup gets fixed later <-- danvet */
+ list_move_tail(&i915_gem_obj_to_vma(obj, vm)->mm_list, &vm->active_list);
+ i915_gem_object_move_to_active(obj, ring);
if (obj->base.write_domain) {
obj->dirty = 1;
obj->last_write_seqno = intel_ring_get_seqno(ring);
@@ -964,11 +885,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct i915_address_space *vm)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct eb_vmas *eb;
+ struct eb_objects *eb;
struct drm_i915_gem_object *batch_obj;
struct drm_clip_rect *cliprects = NULL;
struct intel_ring_buffer *ring;
- struct i915_ctx_hang_stats *hs;
u32 ctx_id = i915_execbuffer2_get_context_id(*args);
u32 exec_start, exec_len;
u32 mask, flags;
@@ -1080,8 +1000,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}
- cliprects = kcalloc(args->num_cliprects,
- sizeof(*cliprects),
+ cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
GFP_KERNEL);
if (cliprects == NULL) {
ret = -ENOMEM;
@@ -1106,7 +1025,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
goto pre_mutex_err;
}
- eb = eb_create(args, vm);
+ eb = eb_create(args);
if (eb == NULL) {
mutex_unlock(&dev->struct_mutex);
ret = -ENOMEM;
@@ -1114,16 +1033,18 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}
/* Look up object handles */
- ret = eb_lookup_vmas(eb, exec, args, vm, file);
+ ret = eb_lookup_objects(eb, exec, args, file);
if (ret)
goto err;
/* take note of the batch buffer before we might reorder the lists */
- batch_obj = list_entry(eb->vmas.prev, struct i915_vma, exec_list)->obj;
+ batch_obj = list_entry(eb->objects.prev,
+ struct drm_i915_gem_object,
+ exec_list);
/* Move the objects en-masse into the GTT, evicting if necessary. */
need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
- ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs);
+ ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs);
if (ret)
goto err;
@@ -1133,7 +1054,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
if (ret) {
if (ret == -EFAULT) {
ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring,
- eb, exec);
+ eb, exec, vm);
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
}
if (ret)
@@ -1150,25 +1071,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
/* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
* batch" bit. Hence we need to pin secure batches into the global gtt.
- * hsw should have this fixed, but bdw mucks it up again. */
+ * hsw should have this fixed, but let's be paranoid and do it
+ * unconditionally for now. */
if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping)
i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level);
- ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->vmas);
+ ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->objects);
if (ret)
goto err;
- hs = i915_gem_context_get_hang_stats(dev, file, ctx_id);
- if (IS_ERR(hs)) {
- ret = PTR_ERR(hs);
- goto err;
- }
-
- if (hs->banned) {
- ret = -EIO;
- goto err;
- }
-
ret = i915_switch_context(ring, file, ctx_id);
if (ret)
goto err;
@@ -1220,7 +1131,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
- i915_gem_execbuffer_move_to_active(&eb->vmas, ring);
+ i915_gem_execbuffer_move_to_active(&eb->objects, vm, ring);
i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
err:
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 38cb8d4..1f7b4ca 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -30,8 +30,6 @@
#define GEN6_PPGTT_PD_ENTRIES 512
#define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t))
-typedef uint64_t gen8_gtt_pte_t;
-typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
/* PPGTT stuff */
#define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0))
@@ -57,44 +55,7 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
#define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2)
#define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3)
#define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb)
-#define HSW_WB_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x8)
#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6)
-#define HSW_WT_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x7)
-
-#define GEN8_PTES_PER_PAGE (PAGE_SIZE / sizeof(gen8_gtt_pte_t))
-#define GEN8_PDES_PER_PAGE (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t))
-#define GEN8_LEGACY_PDPS 4
-
-#define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD)
-#define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */
-#define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */
-#define PPAT_DISPLAY_ELLC_INDEX _PAGE_PCD /* WT eLLC */
-
-static inline gen8_gtt_pte_t gen8_pte_encode(dma_addr_t addr,
- enum i915_cache_level level,
- bool valid)
-{
- gen8_gtt_pte_t pte = valid ? _PAGE_PRESENT | _PAGE_RW : 0;
- pte |= addr;
- if (level != I915_CACHE_NONE)
- pte |= PPAT_CACHED_INDEX;
- else
- pte |= PPAT_UNCACHED_INDEX;
- return pte;
-}
-
-static inline gen8_ppgtt_pde_t gen8_pde_encode(struct drm_device *dev,
- dma_addr_t addr,
- enum i915_cache_level level)
-{
- gen8_ppgtt_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
- pde |= addr;
- if (level != I915_CACHE_NONE)
- pde |= PPAT_CACHED_PDE_INDEX;
- else
- pde |= PPAT_UNCACHED_INDEX;
- return pde;
-}
static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
@@ -187,267 +148,16 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
case I915_CACHE_NONE:
break;
case I915_CACHE_WT:
- pte |= HSW_WT_ELLC_LLC_AGE3;
+ pte |= HSW_WT_ELLC_LLC_AGE0;
break;
default:
- pte |= HSW_WB_ELLC_LLC_AGE3;
+ pte |= HSW_WB_ELLC_LLC_AGE0;
break;
}
return pte;
}
-/* Broadwell Page Directory Pointer Descriptors */
-static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry,
- uint64_t val)
-{
- int ret;
-
- BUG_ON(entry >= 4);
-
- ret = intel_ring_begin(ring, 6);
- if (ret)
- return ret;
-
- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(ring, GEN8_RING_PDP_UDW(ring, entry));
- intel_ring_emit(ring, (u32)(val >> 32));
- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(ring, GEN8_RING_PDP_LDW(ring, entry));
- intel_ring_emit(ring, (u32)(val));
- intel_ring_advance(ring);
-
- return 0;
-}
-
-static int gen8_ppgtt_enable(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *ring;
- struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
- int i, j, ret;
-
- /* bit of a hack to find the actual last used pd */
- int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE;
-
- for_each_ring(ring, dev_priv, j) {
- I915_WRITE(RING_MODE_GEN7(ring),
- _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
- }
-
- for (i = used_pd - 1; i >= 0; i--) {
- dma_addr_t addr = ppgtt->pd_dma_addr[i];
- for_each_ring(ring, dev_priv, j) {
- ret = gen8_write_pdp(ring, i, addr);
- if (ret)
- return ret;
- }
- }
- return 0;
-}
-
-static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
- unsigned first_entry,
- unsigned num_entries,
- bool use_scratch)
-{
- struct i915_hw_ppgtt *ppgtt =
- container_of(vm, struct i915_hw_ppgtt, base);
- gen8_gtt_pte_t *pt_vaddr, scratch_pte;
- unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE;
- unsigned first_pte = first_entry % GEN8_PTES_PER_PAGE;
- unsigned last_pte, i;
-
- scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr,
- I915_CACHE_LLC, use_scratch);
-
- while (num_entries) {
- struct page *page_table = &ppgtt->gen8_pt_pages[act_pt];
-
- last_pte = first_pte + num_entries;
- if (last_pte > GEN8_PTES_PER_PAGE)
- last_pte = GEN8_PTES_PER_PAGE;
-
- pt_vaddr = kmap_atomic(page_table);
-
- for (i = first_pte; i < last_pte; i++)
- pt_vaddr[i] = scratch_pte;
-
- kunmap_atomic(pt_vaddr);
-
- num_entries -= last_pte - first_pte;
- first_pte = 0;
- act_pt++;
- }
-}
-
-static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *pages,
- unsigned first_entry,
- enum i915_cache_level cache_level)
-{
- struct i915_hw_ppgtt *ppgtt =
- container_of(vm, struct i915_hw_ppgtt, base);
- gen8_gtt_pte_t *pt_vaddr;
- unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE;
- unsigned act_pte = first_entry % GEN8_PTES_PER_PAGE;
- struct sg_page_iter sg_iter;
-
- pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]);
- for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
- dma_addr_t page_addr;
-
- page_addr = sg_dma_address(sg_iter.sg) +
- (sg_iter.sg_pgoffset << PAGE_SHIFT);
- pt_vaddr[act_pte] = gen8_pte_encode(page_addr, cache_level,
- true);
- if (++act_pte == GEN8_PTES_PER_PAGE) {
- kunmap_atomic(pt_vaddr);
- act_pt++;
- pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]);
- act_pte = 0;
-
- }
- }
- kunmap_atomic(pt_vaddr);
-}
-
-static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
-{
- struct i915_hw_ppgtt *ppgtt =
- container_of(vm, struct i915_hw_ppgtt, base);
- int i, j;
-
- for (i = 0; i < ppgtt->num_pd_pages ; i++) {
- if (ppgtt->pd_dma_addr[i]) {
- pci_unmap_page(ppgtt->base.dev->pdev,
- ppgtt->pd_dma_addr[i],
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-
- for (j = 0; j < GEN8_PDES_PER_PAGE; j++) {
- dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j];
- if (addr)
- pci_unmap_page(ppgtt->base.dev->pdev,
- addr,
- PAGE_SIZE,
- PCI_DMA_BIDIRECTIONAL);
-
- }
- }
- kfree(ppgtt->gen8_pt_dma_addr[i]);
- }
-
- __free_pages(ppgtt->gen8_pt_pages, ppgtt->num_pt_pages << PAGE_SHIFT);
- __free_pages(ppgtt->pd_pages, ppgtt->num_pd_pages << PAGE_SHIFT);
-}
-
-/**
- * GEN8 legacy ppgtt programming is accomplished through 4 PDP registers with a
- * net effect resembling a 2-level page table in normal x86 terms. Each PDP
- * represents 1GB of memory
- * 4 * 512 * 512 * 4096 = 4GB legacy 32b address space.
- *
- * TODO: Do something with the size parameter
- **/
-static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
-{
- struct page *pt_pages;
- int i, j, ret = -ENOMEM;
- const int max_pdp = DIV_ROUND_UP(size, 1 << 30);
- const int num_pt_pages = GEN8_PDES_PER_PAGE * max_pdp;
-
- if (size % (1<<30))
- DRM_INFO("Pages will be wasted unless GTT size (%llu) is divisible by 1GB\n", size);
-
- /* FIXME: split allocation into smaller pieces. For now we only ever do
- * this once, but with full PPGTT, the multiple contiguous allocations
- * will be bad.
- */
- ppgtt->pd_pages = alloc_pages(GFP_KERNEL, get_order(max_pdp << PAGE_SHIFT));
- if (!ppgtt->pd_pages)
- return -ENOMEM;
-
- pt_pages = alloc_pages(GFP_KERNEL, get_order(num_pt_pages << PAGE_SHIFT));
- if (!pt_pages) {
- __free_pages(ppgtt->pd_pages, get_order(max_pdp << PAGE_SHIFT));
- return -ENOMEM;
- }
-
- ppgtt->gen8_pt_pages = pt_pages;
- ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT);
- ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT);
- ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
- ppgtt->enable = gen8_ppgtt_enable;
- ppgtt->base.clear_range = gen8_ppgtt_clear_range;
- ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
- ppgtt->base.cleanup = gen8_ppgtt_cleanup;
-
- BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS);
-
- /*
- * - Create a mapping for the page directories.
- * - For each page directory:
- * allocate space for page table mappings.
- * map each page table
- */
- for (i = 0; i < max_pdp; i++) {
- dma_addr_t temp;
- temp = pci_map_page(ppgtt->base.dev->pdev,
- &ppgtt->pd_pages[i], 0,
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp))
- goto err_out;
-
- ppgtt->pd_dma_addr[i] = temp;
-
- ppgtt->gen8_pt_dma_addr[i] = kmalloc(sizeof(dma_addr_t) * GEN8_PDES_PER_PAGE, GFP_KERNEL);
- if (!ppgtt->gen8_pt_dma_addr[i])
- goto err_out;
-
- for (j = 0; j < GEN8_PDES_PER_PAGE; j++) {
- struct page *p = &pt_pages[i * GEN8_PDES_PER_PAGE + j];
- temp = pci_map_page(ppgtt->base.dev->pdev,
- p, 0, PAGE_SIZE,
- PCI_DMA_BIDIRECTIONAL);
-
- if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp))
- goto err_out;
-
- ppgtt->gen8_pt_dma_addr[i][j] = temp;
- }
- }
-
- /* For now, the PPGTT helper functions all require that the PDEs are
- * plugged in correctly. So we do that now/here. For aliasing PPGTT, we
- * will never need to touch the PDEs again */
- for (i = 0; i < max_pdp; i++) {
- gen8_ppgtt_pde_t *pd_vaddr;
- pd_vaddr = kmap_atomic(&ppgtt->pd_pages[i]);
- for (j = 0; j < GEN8_PDES_PER_PAGE; j++) {
- dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j];
- pd_vaddr[j] = gen8_pde_encode(ppgtt->base.dev, addr,
- I915_CACHE_LLC);
- }
- kunmap_atomic(pd_vaddr);
- }
-
- ppgtt->base.clear_range(&ppgtt->base, 0,
- ppgtt->num_pd_entries * GEN8_PTES_PER_PAGE,
- true);
-
- DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d wasted)\n",
- ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp);
- DRM_DEBUG_DRIVER("Allocated %d pages for page tables (%lld wasted)\n",
- ppgtt->num_pt_pages,
- (ppgtt->num_pt_pages - num_pt_pages) +
- size % (1<<30));
- return 0;
-
-err_out:
- ppgtt->base.cleanup(&ppgtt->base);
- return ret;
-}
-
static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
{
struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
@@ -632,7 +342,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
ppgtt->base.cleanup = gen6_ppgtt_cleanup;
ppgtt->base.scratch = dev_priv->gtt.base.scratch;
- ppgtt->pt_pages = kcalloc(ppgtt->num_pd_entries, sizeof(struct page *),
+ ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries,
GFP_KERNEL);
if (!ppgtt->pt_pages)
return -ENOMEM;
@@ -643,7 +353,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
goto err_pt_alloc;
}
- ppgtt->pt_dma_addr = kcalloc(ppgtt->num_pd_entries, sizeof(dma_addr_t),
+ ppgtt->pt_dma_addr = kzalloc(sizeof(dma_addr_t) *ppgtt->num_pd_entries,
GFP_KERNEL);
if (!ppgtt->pt_dma_addr)
goto err_pt_alloc;
@@ -700,8 +410,6 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
if (INTEL_INFO(dev)->gen < 8)
ret = gen6_ppgtt_init(ppgtt);
- else if (IS_GEN8(dev))
- ret = gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total);
else
BUG();
@@ -865,57 +573,6 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj)
return 0;
}
-static inline void gen8_set_pte(void __iomem *addr, gen8_gtt_pte_t pte)
-{
-#ifdef writeq
- writeq(pte, addr);
-#else
- iowrite32((u32)pte, addr);
- iowrite32(pte >> 32, addr + 4);
-#endif
-}
-
-static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *st,
- unsigned int first_entry,
- enum i915_cache_level level)
-{
- struct drm_i915_private *dev_priv = vm->dev->dev_private;
- gen8_gtt_pte_t __iomem *gtt_entries =
- (gen8_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry;
- int i = 0;
- struct sg_page_iter sg_iter;
- dma_addr_t addr;
-
- for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
- addr = sg_dma_address(sg_iter.sg) +
- (sg_iter.sg_pgoffset << PAGE_SHIFT);
- gen8_set_pte(&gtt_entries[i],
- gen8_pte_encode(addr, level, true));
- i++;
- }
-
- /*
- * XXX: This serves as a posting read to make sure that the PTE has
- * actually been updated. There is some concern that even though
- * registers and PTEs are within the same BAR that they are potentially
- * of NUMA access patterns. Therefore, even with the way we assume
- * hardware should work, we must keep this posting read for paranoia.
- */
- if (i != 0)
- WARN_ON(readq(&gtt_entries[i-1])
- != gen8_pte_encode(addr, level, true));
-
-#if 0 /* TODO: Still needed on GEN8? */
- /* This next bit makes the above posting read even more important. We
- * want to flush the TLBs only after we're certain all the PTE updates
- * have finished.
- */
- I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
- POSTING_READ(GFX_FLSH_CNTL_GEN6);
-#endif
-}
-
/*
* Binds an object into the global gtt with the specified cache level. The object
* will be accessible to the GPU via commands whose operands reference offsets
@@ -958,30 +615,6 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
POSTING_READ(GFX_FLSH_CNTL_GEN6);
}
-static void gen8_ggtt_clear_range(struct i915_address_space *vm,
- unsigned int first_entry,
- unsigned int num_entries,
- bool use_scratch)
-{
- struct drm_i915_private *dev_priv = vm->dev->dev_private;
- gen8_gtt_pte_t scratch_pte, __iomem *gtt_base =
- (gen8_gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry;
- const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry;
- int i;
-
- if (WARN(num_entries > max_entries,
- "First entry = %d; Num entries = %d (max=%d)\n",
- first_entry, num_entries, max_entries))
- num_entries = max_entries;
-
- scratch_pte = gen8_pte_encode(vm->scratch.addr,
- I915_CACHE_LLC,
- use_scratch);
- for (i = 0; i < num_entries; i++)
- gen8_set_pte(&gtt_base[i], scratch_pte);
- readl(gtt_base);
-}
-
static void gen6_ggtt_clear_range(struct i915_address_space *vm,
unsigned int first_entry,
unsigned int num_entries,
@@ -1005,6 +638,7 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
readl(gtt_base);
}
+
static void i915_ggtt_insert_entries(struct i915_address_space *vm,
struct sg_table *st,
unsigned int pg_start,
@@ -1086,7 +720,6 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node,
*end -= 4096;
}
}
-
void i915_gem_setup_global_gtt(struct drm_device *dev,
unsigned long start,
unsigned long mappable_end,
@@ -1184,8 +817,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
DRM_ERROR("Aliased PPGTT setup failed %d\n", ret);
drm_mm_takedown(&dev_priv->gtt.base.mm);
- if (INTEL_INFO(dev)->gen < 8)
- gtt_size += GEN6_PPGTT_PD_ENTRIES*PAGE_SIZE;
+ gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE;
}
i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
}
@@ -1235,15 +867,6 @@ static inline unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
return snb_gmch_ctl << 20;
}
-static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl)
-{
- bdw_gmch_ctl >>= BDW_GMCH_GGMS_SHIFT;
- bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK;
- if (bdw_gmch_ctl)
- bdw_gmch_ctl = 1 << bdw_gmch_ctl;
- return bdw_gmch_ctl << 20;
-}
-
static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl)
{
snb_gmch_ctl >>= SNB_GMCH_GMS_SHIFT;
@@ -1251,108 +874,6 @@ static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl)
return snb_gmch_ctl << 25; /* 32 MB units */
}
-static inline size_t gen8_get_stolen_size(u16 bdw_gmch_ctl)
-{
- bdw_gmch_ctl >>= BDW_GMCH_GMS_SHIFT;
- bdw_gmch_ctl &= BDW_GMCH_GMS_MASK;
- return bdw_gmch_ctl << 25; /* 32 MB units */
-}
-
-static int ggtt_probe_common(struct drm_device *dev,
- size_t gtt_size)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- phys_addr_t gtt_bus_addr;
- int ret;
-
- /* For Modern GENs the PTEs and register space are split in the BAR */
- gtt_bus_addr = pci_resource_start(dev->pdev, 0) +
- (pci_resource_len(dev->pdev, 0) / 2);
-
- dev_priv->gtt.gsm = ioremap_wc(gtt_bus_addr, gtt_size);
- if (!dev_priv->gtt.gsm) {
- DRM_ERROR("Failed to map the gtt page table\n");
- return -ENOMEM;
- }
-
- ret = setup_scratch_page(dev);
- if (ret) {
- DRM_ERROR("Scratch setup failed\n");
- /* iounmap will also get called at remove, but meh */
- iounmap(dev_priv->gtt.gsm);
- }
-
- return ret;
-}
-
-/* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
- * bits. When using advanced contexts each context stores its own PAT, but
- * writing this data shouldn't be harmful even in those cases. */
-static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv)
-{
-#define GEN8_PPAT_UC (0<<0)
-#define GEN8_PPAT_WC (1<<0)
-#define GEN8_PPAT_WT (2<<0)
-#define GEN8_PPAT_WB (3<<0)
-#define GEN8_PPAT_ELLC_OVERRIDE (0<<2)
-/* FIXME(BDW): Bspec is completely confused about cache control bits. */
-#define GEN8_PPAT_LLC (1<<2)
-#define GEN8_PPAT_LLCELLC (2<<2)
-#define GEN8_PPAT_LLCeLLC (3<<2)
-#define GEN8_PPAT_AGE(x) (x<<4)
-#define GEN8_PPAT(i, x) ((uint64_t) (x) << ((i) * 8))
- uint64_t pat;
-
- pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */
- GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for something pointing to ptes? */
- GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for scanout with eLLC */
- GEN8_PPAT(3, GEN8_PPAT_UC) | /* Uncached objects, mostly for scanout */
- GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) |
- GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) |
- GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) |
- GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
-
- /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b
- * write would work. */
- I915_WRITE(GEN8_PRIVATE_PAT, pat);
- I915_WRITE(GEN8_PRIVATE_PAT + 4, pat >> 32);
-}
-
-static int gen8_gmch_probe(struct drm_device *dev,
- size_t *gtt_total,
- size_t *stolen,
- phys_addr_t *mappable_base,
- unsigned long *mappable_end)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned int gtt_size;
- u16 snb_gmch_ctl;
- int ret;
-
- /* TODO: We're not aware of mappable constraints on gen8 yet */
- *mappable_base = pci_resource_start(dev->pdev, 2);
- *mappable_end = pci_resource_len(dev->pdev, 2);
-
- if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(39)))
- pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(39));
-
- pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
-
- *stolen = gen8_get_stolen_size(snb_gmch_ctl);
-
- gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl);
- *gtt_total = (gtt_size / sizeof(gen8_gtt_pte_t)) << PAGE_SHIFT;
-
- gen8_setup_private_ppat(dev_priv);
-
- ret = ggtt_probe_common(dev, gtt_size);
-
- dev_priv->gtt.base.clear_range = gen8_ggtt_clear_range;
- dev_priv->gtt.base.insert_entries = gen8_ggtt_insert_entries;
-
- return ret;
-}
-
static int gen6_gmch_probe(struct drm_device *dev,
size_t *gtt_total,
size_t *stolen,
@@ -1360,6 +881,7 @@ static int gen6_gmch_probe(struct drm_device *dev,
unsigned long *mappable_end)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ phys_addr_t gtt_bus_addr;
unsigned int gtt_size;
u16 snb_gmch_ctl;
int ret;
@@ -1379,13 +901,24 @@ static int gen6_gmch_probe(struct drm_device *dev,
if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(40)))
pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40));
pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+ gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl);
*stolen = gen6_get_stolen_size(snb_gmch_ctl);
-
- gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl);
*gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT;
- ret = ggtt_probe_common(dev, gtt_size);
+ /* For Modern GENs the PTEs and register space are split in the BAR */
+ gtt_bus_addr = pci_resource_start(dev->pdev, 0) +
+ (pci_resource_len(dev->pdev, 0) / 2);
+
+ dev_priv->gtt.gsm = ioremap_wc(gtt_bus_addr, gtt_size);
+ if (!dev_priv->gtt.gsm) {
+ DRM_ERROR("Failed to map the gtt page table\n");
+ return -ENOMEM;
+ }
+
+ ret = setup_scratch_page(dev);
+ if (ret)
+ DRM_ERROR("Scratch setup failed\n");
dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range;
dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries;
@@ -1439,7 +972,7 @@ int i915_gem_gtt_init(struct drm_device *dev)
if (INTEL_INFO(dev)->gen <= 5) {
gtt->gtt_probe = i915_gmch_probe;
gtt->base.cleanup = i915_gmch_remove;
- } else if (INTEL_INFO(dev)->gen < 8) {
+ } else {
gtt->gtt_probe = gen6_gmch_probe;
gtt->base.cleanup = gen6_gmch_remove;
if (IS_HASWELL(dev) && dev_priv->ellc_size)
@@ -1452,9 +985,6 @@ int i915_gem_gtt_init(struct drm_device *dev)
gtt->base.pte_encode = ivb_pte_encode;
else
gtt->base.pte_encode = snb_pte_encode;
- } else {
- dev_priv->gtt.gtt_probe = gen8_gmch_probe;
- dev_priv->gtt.base.cleanup = gen6_gmch_remove;
}
ret = gtt->gtt_probe(dev, &gtt->base.total, &gtt->stolen_size,
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index d284d89..e15a1d9 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -395,7 +395,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
if (gtt_offset == I915_GTT_OFFSET_NONE)
return obj;
- vma = i915_gem_obj_lookup_or_create_vma(obj, ggtt);
+ vma = i915_gem_vma_create(obj, ggtt);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto err_out;
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index b139053..032e9ef 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -308,7 +308,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
return -EINVAL;
}
- if (obj->pin_count || obj->framebuffer_references) {
+ if (obj->pin_count) {
drm_gem_object_unreference_unlocked(&obj->base);
return -EBUSY;
}
@@ -393,7 +393,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
/* Try to preallocate memory required to save swizzling on put-pages */
if (i915_gem_object_needs_bit17_swizzle(obj)) {
if (obj->bit_17 == NULL) {
- obj->bit_17 = kcalloc(BITS_TO_LONGS(obj->base.size >> PAGE_SHIFT),
+ obj->bit_17 = kmalloc(BITS_TO_LONGS(obj->base.size >> PAGE_SHIFT) *
sizeof(long), GFP_KERNEL);
}
} else {
@@ -504,8 +504,8 @@ i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
int i;
if (obj->bit_17 == NULL) {
- obj->bit_17 = kcalloc(BITS_TO_LONGS(page_count),
- sizeof(long), GFP_KERNEL);
+ obj->bit_17 = kmalloc(BITS_TO_LONGS(page_count) *
+ sizeof(long), GFP_KERNEL);
if (obj->bit_17 == NULL) {
DRM_ERROR("Failed to allocate memory for bit 17 "
"record\n");
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 79dcb8f..dae364f 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -215,24 +215,6 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m,
}
}
-static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a)
-{
- switch (a) {
- case HANGCHECK_IDLE:
- return "idle";
- case HANGCHECK_WAIT:
- return "wait";
- case HANGCHECK_ACTIVE:
- return "active";
- case HANGCHECK_KICK:
- return "kick";
- case HANGCHECK_HUNG:
- return "hung";
- }
-
- return "unknown";
-}
-
static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
struct drm_device *dev,
struct drm_i915_error_state *error,
@@ -249,8 +231,7 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]);
if (ring == RCS && INTEL_INFO(dev)->gen >= 4)
err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr);
- if (INTEL_INFO(dev)->gen >= 4)
- err_printf(m, " BB_STATE: 0x%08x\n", error->bbstate[ring]);
+
if (INTEL_INFO(dev)->gen >= 4)
err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]);
err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]);
@@ -274,9 +255,6 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
err_printf(m, " waiting: %s\n", yesno(error->waiting[ring]));
err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]);
err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]);
- err_printf(m, " hangcheck: %s [%d]\n",
- hangcheck_action_to_str(error->hangcheck_action[ring]),
- error->hangcheck_score[ring]);
}
void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
@@ -305,14 +283,13 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
error->time.tv_usec);
err_printf(m, "Kernel: " UTS_RELEASE "\n");
- err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device);
+ err_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
err_printf(m, "EIR: 0x%08x\n", error->eir);
err_printf(m, "IER: 0x%08x\n", error->ier);
err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
err_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
err_printf(m, "CCID: 0x%08x\n", error->ccid);
- err_printf(m, "Missed interrupts: 0x%08lx\n", dev_priv->gpu_error.missed_irq_rings);
for (i = 0; i < dev_priv->num_fence_regs; i++)
err_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]);
@@ -624,7 +601,6 @@ static void i915_gem_record_fences(struct drm_device *dev,
/* Fences */
switch (INTEL_INFO(dev)->gen) {
- case 8:
case 7:
case 6:
for (i = 0; i < dev_priv->num_fence_regs; i++)
@@ -727,7 +703,6 @@ static void i915_record_ring_state(struct drm_device *dev,
error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base));
if (ring->id == RCS)
error->bbaddr = I915_READ64(BB_ADDR);
- error->bbstate[ring->id] = I915_READ(RING_BBSTATE(ring->mmio_base));
} else {
error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX);
error->ipeir[ring->id] = I915_READ(IPEIR);
@@ -745,9 +720,6 @@ static void i915_record_ring_state(struct drm_device *dev,
error->cpu_ring_head[ring->id] = ring->head;
error->cpu_ring_tail[ring->id] = ring->tail;
-
- error->hangcheck_score[ring->id] = ring->hangcheck.score;
- error->hangcheck_action[ring->id] = ring->hangcheck.action;
}
@@ -797,7 +769,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
error->ring[i].num_requests = count;
error->ring[i].requests =
- kcalloc(count, sizeof(*error->ring[i].requests),
+ kmalloc(count*sizeof(struct drm_i915_error_request),
GFP_ATOMIC);
if (error->ring[i].requests == NULL) {
error->ring[i].num_requests = 0;
@@ -839,7 +811,7 @@ static void i915_gem_capture_vm(struct drm_i915_private *dev_priv,
error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx];
if (i) {
- active_bo = kcalloc(i, sizeof(*active_bo), GFP_ATOMIC);
+ active_bo = kmalloc(sizeof(*active_bo)*i, GFP_ATOMIC);
if (active_bo)
pinned_bo = active_bo + error->active_bo_count[ndx];
}
@@ -913,12 +885,8 @@ void i915_capture_error_state(struct drm_device *dev)
return;
}
- DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n",
- dev->primary->index);
- DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n");
- DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n");
- DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n");
- DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n");
+ DRM_INFO("capturing error event; look for more information in "
+ "/sys/class/drm/card%d/error\n", dev->primary->index);
kref_init(&error->ref);
error->eir = I915_READ(EIR);
@@ -1020,7 +988,6 @@ const char *i915_cache_level_str(int type)
case I915_CACHE_NONE: return " uncached";
case I915_CACHE_LLC: return " snooped or LLC";
case I915_CACHE_L3_LLC: return " L3+LLC";
- case I915_CACHE_WT: return " WT";
default: return "";
}
}
@@ -1045,7 +1012,6 @@ void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone)
default:
WARN_ONCE(1, "Unsupported platform\n");
case 7:
- case 8:
instdone[0] = I915_READ(GEN7_INSTDONE_1);
instdone[1] = I915_READ(GEN7_SC_INSTDONE);
instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5d1dedc..4b91228 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -30,7 +30,6 @@
#include <linux/sysrq.h>
#include <linux/slab.h>
-#include <linux/circ_buf.h>
#include <drm/drmP.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
@@ -270,21 +269,6 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
}
}
-static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev,
- enum pipe pipe, bool enable)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- assert_spin_locked(&dev_priv->irq_lock);
-
- if (enable)
- dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_FIFO_UNDERRUN;
- else
- dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_FIFO_UNDERRUN;
- I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
- POSTING_READ(GEN8_DE_PIPE_IMR(pipe));
-}
-
/**
* ibx_display_interrupt_update - update SDEIMR
* @dev_priv: driver private
@@ -397,8 +381,6 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
else if (IS_GEN7(dev))
ivybridge_set_fifo_underrun_reporting(dev, pipe, enable);
- else if (IS_GEN8(dev))
- broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
done:
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
@@ -459,7 +441,7 @@ done:
void
-i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask)
+i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
{
u32 reg = PIPESTAT(pipe);
u32 pipestat = I915_READ(reg) & 0x7fff0000;
@@ -476,7 +458,7 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask)
}
void
-i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask)
+i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
{
u32 reg = PIPESTAT(pipe);
u32 pipestat = I915_READ(reg) & 0x7fff0000;
@@ -504,10 +486,9 @@ static void i915_enable_asle_pipestat(struct drm_device *dev)
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_ENABLE);
+ i915_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE);
if (INTEL_INFO(dev)->gen >= 4)
- i915_enable_pipestat(dev_priv, PIPE_A,
- PIPE_LEGACY_BLC_EVENT_ENABLE);
+ i915_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}
@@ -537,12 +518,6 @@ i915_pipe_enabled(struct drm_device *dev, int pipe)
}
}
-static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe)
-{
- /* Gen2 doesn't have a hardware frame counter */
- return 0;
-}
-
/* Called from drm generic code, passed a 'crtc', which
* we use as a pipe index
*/
@@ -551,7 +526,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long high_frame;
unsigned long low_frame;
- u32 high1, high2, low, pixel, vbl_start;
+ u32 high1, high2, low;
if (!i915_pipe_enabled(dev, pipe)) {
DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
@@ -559,24 +534,6 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
return 0;
}
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- struct intel_crtc *intel_crtc =
- to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
- const struct drm_display_mode *mode =
- &intel_crtc->config.adjusted_mode;
-
- vbl_start = mode->crtc_vblank_start * mode->crtc_htotal;
- } else {
- enum transcoder cpu_transcoder =
- intel_pipe_to_cpu_transcoder(dev_priv, pipe);
- u32 htotal;
-
- htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1;
- vbl_start = (I915_READ(VBLANK(cpu_transcoder)) & 0x1fff) + 1;
-
- vbl_start *= htotal;
- }
-
high_frame = PIPEFRAME(pipe);
low_frame = PIPEFRAMEPIXEL(pipe);
@@ -587,20 +544,13 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
*/
do {
high1 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK;
- low = I915_READ(low_frame);
+ low = I915_READ(low_frame) & PIPE_FRAME_LOW_MASK;
high2 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK;
} while (high1 != high2);
high1 >>= PIPE_FRAME_HIGH_SHIFT;
- pixel = low & PIPE_PIXEL_MASK;
low >>= PIPE_FRAME_LOW_SHIFT;
-
- /*
- * The frame counter increments at beginning of active.
- * Cook up a vblank counter by also checking the pixel
- * counter against vblank start.
- */
- return ((high1 << 8) | low) + (pixel >= vbl_start);
+ return (high1 << 8) | low;
}
static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
@@ -617,163 +567,66 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
return I915_READ(reg);
}
-/* raw reads, only for fast reads of display block, no need for forcewake etc. */
-#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
-#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))
-
-static bool intel_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t status;
- int reg;
-
- if (IS_VALLEYVIEW(dev)) {
- status = pipe == PIPE_A ?
- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
-
- reg = VLV_ISR;
- } else if (IS_GEN2(dev)) {
- status = pipe == PIPE_A ?
- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
-
- reg = ISR;
- } else if (INTEL_INFO(dev)->gen < 5) {
- status = pipe == PIPE_A ?
- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT :
- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
-
- reg = ISR;
- } else if (INTEL_INFO(dev)->gen < 7) {
- status = pipe == PIPE_A ?
- DE_PIPEA_VBLANK :
- DE_PIPEB_VBLANK;
-
- reg = DEISR;
- } else {
- switch (pipe) {
- default:
- case PIPE_A:
- status = DE_PIPEA_VBLANK_IVB;
- break;
- case PIPE_B:
- status = DE_PIPEB_VBLANK_IVB;
- break;
- case PIPE_C:
- status = DE_PIPEC_VBLANK_IVB;
- break;
- }
-
- reg = DEISR;
- }
-
- if (IS_GEN2(dev))
- return __raw_i915_read16(dev_priv, reg) & status;
- else
- return __raw_i915_read32(dev_priv, reg) & status;
-}
-
static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
- int *vpos, int *hpos, ktime_t *stime, ktime_t *etime)
+ int *vpos, int *hpos)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
- int position;
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ u32 vbl = 0, position = 0;
int vbl_start, vbl_end, htotal, vtotal;
bool in_vbl = true;
int ret = 0;
- unsigned long irqflags;
+ enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
+ pipe);
- if (!intel_crtc->active) {
+ if (!i915_pipe_enabled(dev, pipe)) {
DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
"pipe %c\n", pipe_name(pipe));
return 0;
}
- htotal = mode->crtc_htotal;
- vtotal = mode->crtc_vtotal;
- vbl_start = mode->crtc_vblank_start;
- vbl_end = mode->crtc_vblank_end;
-
- ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
+ /* Get vtotal. */
+ vtotal = 1 + ((I915_READ(VTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
- /*
- * Lock uncore.lock, as we will do multiple timing critical raw
- * register reads, potentially with preemption disabled, so the
- * following code must not block on uncore.lock.
- */
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
- /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
-
- /* Get optional system timestamp before query. */
- if (stime)
- *stime = ktime_get();
-
- if (IS_GEN2(dev) || IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+ if (INTEL_INFO(dev)->gen >= 4) {
/* No obvious pixelcount register. Only query vertical
* scanout position from Display scan line register.
*/
- if (IS_GEN2(dev))
- position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN2;
- else
- position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
+ position = I915_READ(PIPEDSL(pipe));
- /*
- * The scanline counter increments at the leading edge
- * of hsync, ie. it completely misses the active portion
- * of the line. Fix up the counter at both edges of vblank
- * to get a more accurate picture whether we're in vblank
- * or not.
+ /* Decode into vertical scanout position. Don't have
+ * horizontal scanout position.
*/
- in_vbl = intel_pipe_in_vblank_locked(dev, pipe);
- if ((in_vbl && position == vbl_start - 1) ||
- (!in_vbl && position == vbl_end - 1))
- position = (position + 1) % vtotal;
+ *vpos = position & 0x1fff;
+ *hpos = 0;
} else {
/* Have access to pixelcount since start of frame.
* We can split this into vertical and horizontal
* scanout position.
*/
- position = (__raw_i915_read32(dev_priv, PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
+ position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
- /* convert to pixel counts */
- vbl_start *= htotal;
- vbl_end *= htotal;
- vtotal *= htotal;
+ htotal = 1 + ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
+ *vpos = position / htotal;
+ *hpos = position - (*vpos * htotal);
}
- /* Get optional system timestamp after query. */
- if (etime)
- *etime = ktime_get();
+ /* Query vblank area. */
+ vbl = I915_READ(VBLANK(cpu_transcoder));
- /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
+ /* Test position against vblank region. */
+ vbl_start = vbl & 0x1fff;
+ vbl_end = (vbl >> 16) & 0x1fff;
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+ if ((*vpos < vbl_start) || (*vpos > vbl_end))
+ in_vbl = false;
- in_vbl = position >= vbl_start && position < vbl_end;
+ /* Inside "upper part" of vblank area? Apply corrective offset: */
+ if (in_vbl && (*vpos >= vbl_start))
+ *vpos = *vpos - vtotal;
- /*
- * While in vblank, position will be negative
- * counting up towards 0 at vbl_end. And outside
- * vblank, position will be positive counting
- * up since vbl_end.
- */
- if (position >= vbl_start)
- position -= vbl_end;
- else
- position += vtotal - vbl_end;
-
- if (IS_GEN2(dev) || IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
- *vpos = position;
- *hpos = 0;
- } else {
- *vpos = position / htotal;
- *hpos = position - (*vpos * htotal);
- }
+ /* Readouts valid? */
+ if (vbl > 0)
+ ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
/* In vblank? */
if (in_vbl)
@@ -812,8 +665,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
crtc);
}
-static bool intel_hpd_irq_event(struct drm_device *dev,
- struct drm_connector *connector)
+static int intel_hpd_irq_event(struct drm_device *dev, struct drm_connector *connector)
{
enum drm_connector_status old_status;
@@ -821,16 +673,11 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
old_status = connector->status;
connector->status = connector->funcs->detect(connector, false);
- if (old_status == connector->status)
- return false;
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
connector->base.id,
drm_get_connector_name(connector),
- drm_get_connector_status_name(old_status),
- drm_get_connector_status_name(connector->status));
-
- return true;
+ old_status, connector->status);
+ return (old_status != connector->status);
}
/*
@@ -954,7 +801,7 @@ static void notify_ring(struct drm_device *dev,
if (ring->obj == NULL)
return;
- trace_i915_gem_request_complete(ring);
+ trace_i915_gem_request_complete(ring, ring->get_seqno(ring, false));
wake_up_all(&ring->irq_queue);
i915_queue_hangcheck(dev);
@@ -965,7 +812,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
rps.work);
u32 pm_iir;
- int new_delay, adj;
+ u8 new_delay;
spin_lock_irq(&dev_priv->irq_lock);
pm_iir = dev_priv->rps.pm_iir;
@@ -982,49 +829,40 @@ static void gen6_pm_rps_work(struct work_struct *work)
mutex_lock(&dev_priv->rps.hw_lock);
- adj = dev_priv->rps.last_adj;
if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
- if (adj > 0)
- adj *= 2;
- else
- adj = 1;
- new_delay = dev_priv->rps.cur_delay + adj;
+ new_delay = dev_priv->rps.cur_delay + 1;
/*
* For better performance, jump directly
* to RPe if we're below it.
*/
- if (new_delay < dev_priv->rps.rpe_delay)
- new_delay = dev_priv->rps.rpe_delay;
- } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
- if (dev_priv->rps.cur_delay > dev_priv->rps.rpe_delay)
+ if (IS_VALLEYVIEW(dev_priv->dev) &&
+ dev_priv->rps.cur_delay < dev_priv->rps.rpe_delay)
new_delay = dev_priv->rps.rpe_delay;
- else
- new_delay = dev_priv->rps.min_delay;
- adj = 0;
- } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
- if (adj < 0)
- adj *= 2;
- else
- adj = -1;
- new_delay = dev_priv->rps.cur_delay + adj;
- } else { /* unknown event */
- new_delay = dev_priv->rps.cur_delay;
- }
+ } else
+ new_delay = dev_priv->rps.cur_delay - 1;
/* sysfs frequency interfaces may have snuck in while servicing the
* interrupt
*/
- if (new_delay < (int)dev_priv->rps.min_delay)
- new_delay = dev_priv->rps.min_delay;
- if (new_delay > (int)dev_priv->rps.max_delay)
- new_delay = dev_priv->rps.max_delay;
- dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_delay;
-
- if (IS_VALLEYVIEW(dev_priv->dev))
- valleyview_set_rps(dev_priv->dev, new_delay);
- else
- gen6_set_rps(dev_priv->dev, new_delay);
+ if (new_delay >= dev_priv->rps.min_delay &&
+ new_delay <= dev_priv->rps.max_delay) {
+ if (IS_VALLEYVIEW(dev_priv->dev))
+ valleyview_set_rps(dev_priv->dev, new_delay);
+ else
+ gen6_set_rps(dev_priv->dev, new_delay);
+ }
+
+ if (IS_VALLEYVIEW(dev_priv->dev)) {
+ /*
+ * On VLV, when we enter RC6 we may not be at the minimum
+ * voltage level, so arm a timer to check. It should only
+ * fire when there's activity or once after we've entered
+ * RC6, and then won't be re-armed until the next RPS interrupt.
+ */
+ mod_delayed_work(dev_priv->wq, &dev_priv->rps.vlv_work,
+ msecs_to_jiffies(100));
+ }
mutex_unlock(&dev_priv->rps.hw_lock);
}
@@ -1044,10 +882,9 @@ static void ivybridge_parity_work(struct work_struct *work)
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
l3_parity.error_work);
u32 error_status, row, bank, subbank;
- char *parity_event[6];
+ char *parity_event[5];
uint32_t misccpctl;
unsigned long flags;
- uint8_t slice = 0;
/* We must turn off DOP level clock gating to access the L3 registers.
* In order to prevent a get/put style interface, acquire struct mutex
@@ -1055,81 +892,55 @@ static void ivybridge_parity_work(struct work_struct *work)
*/
mutex_lock(&dev_priv->dev->struct_mutex);
- /* If we've screwed up tracking, just let the interrupt fire again */
- if (WARN_ON(!dev_priv->l3_parity.which_slice))
- goto out;
-
misccpctl = I915_READ(GEN7_MISCCPCTL);
I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
POSTING_READ(GEN7_MISCCPCTL);
- while ((slice = ffs(dev_priv->l3_parity.which_slice)) != 0) {
- u32 reg;
-
- slice--;
- if (WARN_ON_ONCE(slice >= NUM_L3_SLICES(dev_priv->dev)))
- break;
-
- dev_priv->l3_parity.which_slice &= ~(1<<slice);
-
- reg = GEN7_L3CDERRST1 + (slice * 0x200);
-
- error_status = I915_READ(reg);
- row = GEN7_PARITY_ERROR_ROW(error_status);
- bank = GEN7_PARITY_ERROR_BANK(error_status);
- subbank = GEN7_PARITY_ERROR_SUBBANK(error_status);
+ error_status = I915_READ(GEN7_L3CDERRST1);
+ row = GEN7_PARITY_ERROR_ROW(error_status);
+ bank = GEN7_PARITY_ERROR_BANK(error_status);
+ subbank = GEN7_PARITY_ERROR_SUBBANK(error_status);
- I915_WRITE(reg, GEN7_PARITY_ERROR_VALID | GEN7_L3CDERRST1_ENABLE);
- POSTING_READ(reg);
-
- parity_event[0] = I915_L3_PARITY_UEVENT "=1";
- parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row);
- parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank);
- parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank);
- parity_event[4] = kasprintf(GFP_KERNEL, "SLICE=%d", slice);
- parity_event[5] = NULL;
-
- kobject_uevent_env(&dev_priv->dev->primary->kdev->kobj,
- KOBJ_CHANGE, parity_event);
-
- DRM_DEBUG("Parity error: Slice = %d, Row = %d, Bank = %d, Sub bank = %d.\n",
- slice, row, bank, subbank);
-
- kfree(parity_event[4]);
- kfree(parity_event[3]);
- kfree(parity_event[2]);
- kfree(parity_event[1]);
- }
+ I915_WRITE(GEN7_L3CDERRST1, GEN7_PARITY_ERROR_VALID |
+ GEN7_L3CDERRST1_ENABLE);
+ POSTING_READ(GEN7_L3CDERRST1);
I915_WRITE(GEN7_MISCCPCTL, misccpctl);
-out:
- WARN_ON(dev_priv->l3_parity.which_slice);
spin_lock_irqsave(&dev_priv->irq_lock, flags);
- ilk_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv->dev));
+ ilk_enable_gt_irq(dev_priv, GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
mutex_unlock(&dev_priv->dev->struct_mutex);
+
+ parity_event[0] = I915_L3_PARITY_UEVENT "=1";
+ parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row);
+ parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank);
+ parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank);
+ parity_event[4] = NULL;
+
+ kobject_uevent_env(&dev_priv->dev->primary->kdev.kobj,
+ KOBJ_CHANGE, parity_event);
+
+ DRM_DEBUG("Parity error: Row = %d, Bank = %d, Sub bank = %d.\n",
+ row, bank, subbank);
+
+ kfree(parity_event[3]);
+ kfree(parity_event[2]);
+ kfree(parity_event[1]);
}
-static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir)
+static void ivybridge_parity_error_irq_handler(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- if (!HAS_L3_DPF(dev))
+ if (!HAS_L3_GPU_CACHE(dev))
return;
spin_lock(&dev_priv->irq_lock);
- ilk_disable_gt_irq(dev_priv, GT_PARITY_ERROR(dev));
+ ilk_disable_gt_irq(dev_priv, GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
spin_unlock(&dev_priv->irq_lock);
- iir &= GT_PARITY_ERROR(dev);
- if (iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1)
- dev_priv->l3_parity.which_slice |= 1 << 1;
-
- if (iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT)
- dev_priv->l3_parity.which_slice |= 1 << 0;
-
queue_work(dev_priv->wq, &dev_priv->l3_parity.error_work);
}
@@ -1164,58 +975,8 @@ static void snb_gt_irq_handler(struct drm_device *dev,
i915_handle_error(dev, false);
}
- if (gt_iir & GT_PARITY_ERROR(dev))
- ivybridge_parity_error_irq_handler(dev, gt_iir);
-}
-
-static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
- struct drm_i915_private *dev_priv,
- u32 master_ctl)
-{
- u32 rcs, bcs, vcs;
- uint32_t tmp = 0;
- irqreturn_t ret = IRQ_NONE;
-
- if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
- tmp = I915_READ(GEN8_GT_IIR(0));
- if (tmp) {
- ret = IRQ_HANDLED;
- rcs = tmp >> GEN8_RCS_IRQ_SHIFT;
- bcs = tmp >> GEN8_BCS_IRQ_SHIFT;
- if (rcs & GT_RENDER_USER_INTERRUPT)
- notify_ring(dev, &dev_priv->ring[RCS]);
- if (bcs & GT_RENDER_USER_INTERRUPT)
- notify_ring(dev, &dev_priv->ring[BCS]);
- I915_WRITE(GEN8_GT_IIR(0), tmp);
- } else
- DRM_ERROR("The master control interrupt lied (GT0)!\n");
- }
-
- if (master_ctl & GEN8_GT_VCS1_IRQ) {
- tmp = I915_READ(GEN8_GT_IIR(1));
- if (tmp) {
- ret = IRQ_HANDLED;
- vcs = tmp >> GEN8_VCS1_IRQ_SHIFT;
- if (vcs & GT_RENDER_USER_INTERRUPT)
- notify_ring(dev, &dev_priv->ring[VCS]);
- I915_WRITE(GEN8_GT_IIR(1), tmp);
- } else
- DRM_ERROR("The master control interrupt lied (GT1)!\n");
- }
-
- if (master_ctl & GEN8_GT_VECS_IRQ) {
- tmp = I915_READ(GEN8_GT_IIR(3));
- if (tmp) {
- ret = IRQ_HANDLED;
- vcs = tmp >> GEN8_VECS_IRQ_SHIFT;
- if (vcs & GT_RENDER_USER_INTERRUPT)
- notify_ring(dev, &dev_priv->ring[VECS]);
- I915_WRITE(GEN8_GT_IIR(3), tmp);
- } else
- DRM_ERROR("The master control interrupt lied (GT3)!\n");
- }
-
- return ret;
+ if (gt_iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT)
+ ivybridge_parity_error_irq_handler(dev);
}
#define HPD_STORM_DETECT_PERIOD 1000
@@ -1289,102 +1050,6 @@ static void dp_aux_irq_handler(struct drm_device *dev)
wake_up_all(&dev_priv->gmbus_wait_queue);
}
-#if defined(CONFIG_DEBUG_FS)
-static void display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe,
- uint32_t crc0, uint32_t crc1,
- uint32_t crc2, uint32_t crc3,
- uint32_t crc4)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
- struct intel_pipe_crc_entry *entry;
- int head, tail;
-
- spin_lock(&pipe_crc->lock);
-
- if (!pipe_crc->entries) {
- spin_unlock(&pipe_crc->lock);
- DRM_ERROR("spurious interrupt\n");
- return;
- }
-
- head = pipe_crc->head;
- tail = pipe_crc->tail;
-
- if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) {
- spin_unlock(&pipe_crc->lock);
- DRM_ERROR("CRC buffer overflowing\n");
- return;
- }
-
- entry = &pipe_crc->entries[head];
-
- entry->frame = dev->driver->get_vblank_counter(dev, pipe);
- entry->crc[0] = crc0;
- entry->crc[1] = crc1;
- entry->crc[2] = crc2;
- entry->crc[3] = crc3;
- entry->crc[4] = crc4;
-
- head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
- pipe_crc->head = head;
-
- spin_unlock(&pipe_crc->lock);
-
- wake_up_interruptible(&pipe_crc->wq);
-}
-#else
-static inline void
-display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe,
- uint32_t crc0, uint32_t crc1,
- uint32_t crc2, uint32_t crc3,
- uint32_t crc4) {}
-#endif
-
-
-static void hsw_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- display_pipe_crc_irq_handler(dev, pipe,
- I915_READ(PIPE_CRC_RES_1_IVB(pipe)),
- 0, 0, 0, 0);
-}
-
-static void ivb_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- display_pipe_crc_irq_handler(dev, pipe,
- I915_READ(PIPE_CRC_RES_1_IVB(pipe)),
- I915_READ(PIPE_CRC_RES_2_IVB(pipe)),
- I915_READ(PIPE_CRC_RES_3_IVB(pipe)),
- I915_READ(PIPE_CRC_RES_4_IVB(pipe)),
- I915_READ(PIPE_CRC_RES_5_IVB(pipe)));
-}
-
-static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t res1, res2;
-
- if (INTEL_INFO(dev)->gen >= 3)
- res1 = I915_READ(PIPE_CRC_RES_RES1_I915(pipe));
- else
- res1 = 0;
-
- if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
- res2 = I915_READ(PIPE_CRC_RES_RES2_G4X(pipe));
- else
- res2 = 0;
-
- display_pipe_crc_irq_handler(dev, pipe,
- I915_READ(PIPE_CRC_RES_RED(pipe)),
- I915_READ(PIPE_CRC_RES_GREEN(pipe)),
- I915_READ(PIPE_CRC_RES_BLUE(pipe)),
- res1, res2);
-}
-
/* The RPS events need forcewake, so we add them to a work queue and mask their
* IMR bits until the work is done. Other interrupts can be processed without
* the work queue. */
@@ -1452,16 +1117,13 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
for_each_pipe(pipe) {
- if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+ if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
drm_handle_vblank(dev, pipe);
if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) {
intel_prepare_page_flip(dev, pipe);
intel_finish_page_flip(dev, pipe);
}
-
- if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
- i9xx_pipe_crc_irq_handler(dev, pipe);
}
/* Consume port. Then clear IIR or we'll miss events */
@@ -1550,26 +1212,21 @@ static void ivb_err_int_handler(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 err_int = I915_READ(GEN7_ERR_INT);
- enum pipe pipe;
if (err_int & ERR_INT_POISON)
DRM_ERROR("Poison interrupt\n");
- for_each_pipe(pipe) {
- if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) {
- if (intel_set_cpu_fifo_underrun_reporting(dev, pipe,
- false))
- DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n",
- pipe_name(pipe));
- }
+ if (err_int & ERR_INT_FIFO_UNDERRUN_A)
+ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false))
+ DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n");
- if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) {
- if (IS_IVYBRIDGE(dev))
- ivb_pipe_crc_irq_handler(dev, pipe);
- else
- hsw_pipe_crc_irq_handler(dev, pipe);
- }
- }
+ if (err_int & ERR_INT_FIFO_UNDERRUN_B)
+ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false))
+ DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n");
+
+ if (err_int & ERR_INT_FIFO_UNDERRUN_C)
+ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_C, false))
+ DRM_DEBUG_DRIVER("Pipe C FIFO underrun\n");
I915_WRITE(GEN7_ERR_INT, err_int);
}
@@ -1640,7 +1297,6 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe pipe;
if (de_iir & DE_AUX_CHANNEL_A)
dp_aux_irq_handler(dev);
@@ -1648,26 +1304,31 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir)
if (de_iir & DE_GSE)
intel_opregion_asle_intr(dev);
+ if (de_iir & DE_PIPEA_VBLANK)
+ drm_handle_vblank(dev, 0);
+
+ if (de_iir & DE_PIPEB_VBLANK)
+ drm_handle_vblank(dev, 1);
+
if (de_iir & DE_POISON)
DRM_ERROR("Poison interrupt\n");
- for_each_pipe(pipe) {
- if (de_iir & DE_PIPE_VBLANK(pipe))
- drm_handle_vblank(dev, pipe);
+ if (de_iir & DE_PIPEA_FIFO_UNDERRUN)
+ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false))
+ DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n");
- if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
- if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, false))
- DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n",
- pipe_name(pipe));
+ if (de_iir & DE_PIPEB_FIFO_UNDERRUN)
+ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false))
+ DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n");
- if (de_iir & DE_PIPE_CRC_DONE(pipe))
- i9xx_pipe_crc_irq_handler(dev, pipe);
+ if (de_iir & DE_PLANEA_FLIP_DONE) {
+ intel_prepare_page_flip(dev, 0);
+ intel_finish_page_flip_plane(dev, 0);
+ }
- /* plane/pipes map 1:1 on ilk+ */
- if (de_iir & DE_PLANE_FLIP_DONE(pipe)) {
- intel_prepare_page_flip(dev, pipe);
- intel_finish_page_flip_plane(dev, pipe);
- }
+ if (de_iir & DE_PLANEB_FLIP_DONE) {
+ intel_prepare_page_flip(dev, 1);
+ intel_finish_page_flip_plane(dev, 1);
}
/* check event from PCH */
@@ -1690,7 +1351,7 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir)
static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe i;
+ int i;
if (de_iir & DE_ERR_INT_IVB)
ivb_err_int_handler(dev);
@@ -1701,12 +1362,10 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
if (de_iir & DE_GSE_IVB)
intel_opregion_asle_intr(dev);
- for_each_pipe(i) {
- if (de_iir & (DE_PIPE_VBLANK_IVB(i)))
+ for (i = 0; i < 3; i++) {
+ if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
drm_handle_vblank(dev, i);
-
- /* plane/pipes map 1:1 on ilk+ */
- if (de_iir & DE_PLANE_FLIP_DONE_IVB(i)) {
+ if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) {
intel_prepare_page_flip(dev, i);
intel_finish_page_flip_plane(dev, i);
}
@@ -1729,6 +1388,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
+ bool err_int_reenable = false;
atomic_inc(&dev_priv->irq_received);
@@ -1752,6 +1412,17 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
POSTING_READ(SDEIER);
}
+ /* On Haswell, also mask ERR_INT because we don't want to risk
+ * generating "unclaimed register" interrupts from inside the interrupt
+ * handler. */
+ if (IS_HASWELL(dev)) {
+ spin_lock(&dev_priv->irq_lock);
+ err_int_reenable = ~dev_priv->irq_mask & DE_ERR_INT_IVB;
+ if (err_int_reenable)
+ ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
+ spin_unlock(&dev_priv->irq_lock);
+ }
+
gt_iir = I915_READ(GTIIR);
if (gt_iir) {
if (INTEL_INFO(dev)->gen >= 6)
@@ -1781,6 +1452,13 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
}
}
+ if (err_int_reenable) {
+ spin_lock(&dev_priv->irq_lock);
+ if (ivb_can_enable_err_int(dev))
+ ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
+ spin_unlock(&dev_priv->irq_lock);
+ }
+
I915_WRITE(DEIER, de_ier);
POSTING_READ(DEIER);
if (!HAS_PCH_NOP(dev)) {
@@ -1791,117 +1469,6 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
return ret;
}
-static irqreturn_t gen8_irq_handler(int irq, void *arg)
-{
- struct drm_device *dev = arg;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 master_ctl;
- irqreturn_t ret = IRQ_NONE;
- uint32_t tmp = 0;
- enum pipe pipe;
-
- atomic_inc(&dev_priv->irq_received);
-
- master_ctl = I915_READ(GEN8_MASTER_IRQ);
- master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
- if (!master_ctl)
- return IRQ_NONE;
-
- I915_WRITE(GEN8_MASTER_IRQ, 0);
- POSTING_READ(GEN8_MASTER_IRQ);
-
- ret = gen8_gt_irq_handler(dev, dev_priv, master_ctl);
-
- if (master_ctl & GEN8_DE_MISC_IRQ) {
- tmp = I915_READ(GEN8_DE_MISC_IIR);
- if (tmp & GEN8_DE_MISC_GSE)
- intel_opregion_asle_intr(dev);
- else if (tmp)
- DRM_ERROR("Unexpected DE Misc interrupt\n");
- else
- DRM_ERROR("The master control interrupt lied (DE MISC)!\n");
-
- if (tmp) {
- I915_WRITE(GEN8_DE_MISC_IIR, tmp);
- ret = IRQ_HANDLED;
- }
- }
-
- if (master_ctl & GEN8_DE_PORT_IRQ) {
- tmp = I915_READ(GEN8_DE_PORT_IIR);
- if (tmp & GEN8_AUX_CHANNEL_A)
- dp_aux_irq_handler(dev);
- else if (tmp)
- DRM_ERROR("Unexpected DE Port interrupt\n");
- else
- DRM_ERROR("The master control interrupt lied (DE PORT)!\n");
-
- if (tmp) {
- I915_WRITE(GEN8_DE_PORT_IIR, tmp);
- ret = IRQ_HANDLED;
- }
- }
-
- for_each_pipe(pipe) {
- uint32_t pipe_iir;
-
- if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
- continue;
-
- pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe));
- if (pipe_iir & GEN8_PIPE_VBLANK)
- drm_handle_vblank(dev, pipe);
-
- if (pipe_iir & GEN8_PIPE_FLIP_DONE) {
- intel_prepare_page_flip(dev, pipe);
- intel_finish_page_flip_plane(dev, pipe);
- }
-
- if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE)
- hsw_pipe_crc_irq_handler(dev, pipe);
-
- if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) {
- if (intel_set_cpu_fifo_underrun_reporting(dev, pipe,
- false))
- DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n",
- pipe_name(pipe));
- }
-
- if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) {
- DRM_ERROR("Fault errors on pipe %c\n: 0x%08x",
- pipe_name(pipe),
- pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS);
- }
-
- if (pipe_iir) {
- ret = IRQ_HANDLED;
- I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir);
- } else
- DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");
- }
-
- if (!HAS_PCH_NOP(dev) && master_ctl & GEN8_DE_PCH_IRQ) {
- /*
- * FIXME(BDW): Assume for now that the new interrupt handling
- * scheme also closed the SDE interrupt handling race we've seen
- * on older pch-split platforms. But this needs testing.
- */
- u32 pch_iir = I915_READ(SDEIIR);
-
- cpt_irq_handler(dev, pch_iir);
-
- if (pch_iir) {
- I915_WRITE(SDEIIR, pch_iir);
- ret = IRQ_HANDLED;
- }
- }
-
- I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
- POSTING_READ(GEN8_MASTER_IRQ);
-
- return ret;
-}
-
static void i915_error_wake_up(struct drm_i915_private *dev_priv,
bool reset_completed)
{
@@ -1949,7 +1516,7 @@ static void i915_error_work_func(struct work_struct *work)
char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL };
int ret;
- kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, error_event);
+ kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
/*
* Note that there's only one work item which does gpu resets, so we
@@ -1963,7 +1530,7 @@ static void i915_error_work_func(struct work_struct *work)
*/
if (i915_reset_in_progress(error) && !i915_terminally_wedged(error)) {
DRM_DEBUG_DRIVER("resetting chip\n");
- kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE,
+ kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE,
reset_event);
/*
@@ -1990,7 +1557,7 @@ static void i915_error_work_func(struct work_struct *work)
smp_mb__before_atomic_inc();
atomic_inc(&dev_priv->gpu_error.reset_counter);
- kobject_uevent_env(&dev->primary->kdev->kobj,
+ kobject_uevent_env(&dev->primary->kdev.kobj,
KOBJ_CHANGE, reset_done_event);
} else {
atomic_set(&error->reset_counter, I915_WEDGED);
@@ -2220,7 +1787,7 @@ static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
- DE_PIPE_VBLANK(pipe);
+ DE_PIPE_VBLANK_ILK(pipe);
if (!i915_pipe_enabled(dev, pipe))
return -EINVAL;
@@ -2243,7 +1810,7 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
imr = I915_READ(VLV_IMR);
- if (pipe == PIPE_A)
+ if (pipe == 0)
imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
else
imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
@@ -2255,22 +1822,6 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
return 0;
}
-static int gen8_enable_vblank(struct drm_device *dev, int pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long irqflags;
-
- if (!i915_pipe_enabled(dev, pipe))
- return -EINVAL;
-
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_VBLANK;
- I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
- POSTING_READ(GEN8_DE_PIPE_IMR(pipe));
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
- return 0;
-}
-
/* Called from drm generic code, passed 'crtc' which
* we use as a pipe index
*/
@@ -2294,7 +1845,7 @@ static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
- DE_PIPE_VBLANK(pipe);
+ DE_PIPE_VBLANK_ILK(pipe);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
ironlake_disable_display_irq(dev_priv, bit);
@@ -2311,7 +1862,7 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
i915_disable_pipestat(dev_priv, pipe,
PIPE_START_VBLANK_INTERRUPT_ENABLE);
imr = I915_READ(VLV_IMR);
- if (pipe == PIPE_A)
+ if (pipe == 0)
imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
else
imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
@@ -2319,21 +1870,6 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}
-static void gen8_disable_vblank(struct drm_device *dev, int pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long irqflags;
-
- if (!i915_pipe_enabled(dev, pipe))
- return;
-
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_VBLANK;
- I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
- POSTING_READ(GEN8_DE_PIPE_IMR(pipe));
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
-}
-
static u32
ring_last_seqno(struct intel_ring_buffer *ring)
{
@@ -2429,7 +1965,6 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
if (tmp & RING_WAIT) {
DRM_ERROR("Kicking stuck wait on %s\n",
ring->name);
- i915_handle_error(dev, false);
I915_WRITE_CTL(ring, tmp);
return HANGCHECK_KICK;
}
@@ -2441,7 +1976,6 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
case 1:
DRM_ERROR("Kicking stuck semaphore on %s\n",
ring->name);
- i915_handle_error(dev, false);
I915_WRITE_CTL(ring, tmp);
return HANGCHECK_KICK;
case 0:
@@ -2487,21 +2021,12 @@ static void i915_hangcheck_elapsed(unsigned long data)
if (ring->hangcheck.seqno == seqno) {
if (ring_idle(ring, seqno)) {
- ring->hangcheck.action = HANGCHECK_IDLE;
-
if (waitqueue_active(&ring->irq_queue)) {
/* Issue a wake-up to catch stuck h/w. */
- if (!test_and_set_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings)) {
- if (!(dev_priv->gpu_error.test_irq_rings & intel_ring_flag(ring)))
- DRM_ERROR("Hangcheck timer elapsed... %s idle\n",
- ring->name);
- else
- DRM_INFO("Fake missed irq on %s\n",
- ring->name);
- wake_up_all(&ring->irq_queue);
- }
- /* Safeguard against driver failure */
- ring->hangcheck.score += BUSY;
+ DRM_ERROR("Hangcheck timer elapsed... %s idle\n",
+ ring->name);
+ wake_up_all(&ring->irq_queue);
+ ring->hangcheck.score += HUNG;
} else
busy = false;
} else {
@@ -2524,7 +2049,6 @@ static void i915_hangcheck_elapsed(unsigned long data)
acthd);
switch (ring->hangcheck.action) {
- case HANGCHECK_IDLE:
case HANGCHECK_WAIT:
break;
case HANGCHECK_ACTIVE:
@@ -2540,8 +2064,6 @@ static void i915_hangcheck_elapsed(unsigned long data)
}
}
} else {
- ring->hangcheck.action = HANGCHECK_ACTIVE;
-
/* Gradually reduce the count so that we catch DoS
* attempts across multiple batches.
*/
@@ -2668,53 +2190,6 @@ static void valleyview_irq_preinstall(struct drm_device *dev)
POSTING_READ(VLV_IER);
}
-static void gen8_irq_preinstall(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int pipe;
-
- atomic_set(&dev_priv->irq_received, 0);
-
- I915_WRITE(GEN8_MASTER_IRQ, 0);
- POSTING_READ(GEN8_MASTER_IRQ);
-
- /* IIR can theoretically queue up two events. Be paranoid */
-#define GEN8_IRQ_INIT_NDX(type, which) do { \
- I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \
- POSTING_READ(GEN8_##type##_IMR(which)); \
- I915_WRITE(GEN8_##type##_IER(which), 0); \
- I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \
- POSTING_READ(GEN8_##type##_IIR(which)); \
- I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \
- } while (0)
-
-#define GEN8_IRQ_INIT(type) do { \
- I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \
- POSTING_READ(GEN8_##type##_IMR); \
- I915_WRITE(GEN8_##type##_IER, 0); \
- I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \
- POSTING_READ(GEN8_##type##_IIR); \
- I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \
- } while (0)
-
- GEN8_IRQ_INIT_NDX(GT, 0);
- GEN8_IRQ_INIT_NDX(GT, 1);
- GEN8_IRQ_INIT_NDX(GT, 2);
- GEN8_IRQ_INIT_NDX(GT, 3);
-
- for_each_pipe(pipe) {
- GEN8_IRQ_INIT_NDX(DE_PIPE, pipe);
- }
-
- GEN8_IRQ_INIT(DE_PORT);
- GEN8_IRQ_INIT(DE_MISC);
- GEN8_IRQ_INIT(PCU);
-#undef GEN8_IRQ_INIT
-#undef GEN8_IRQ_INIT_NDX
-
- POSTING_READ(GEN8_PCU_IIR);
-}
-
static void ibx_hpd_irq_setup(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -2779,10 +2254,10 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
pm_irqs = gt_irqs = 0;
dev_priv->gt_irq_mask = ~0;
- if (HAS_L3_DPF(dev)) {
+ if (HAS_L3_GPU_CACHE(dev)) {
/* L3 parity interrupt is always unmasked. */
- dev_priv->gt_irq_mask = ~GT_PARITY_ERROR(dev);
- gt_irqs |= GT_PARITY_ERROR(dev);
+ dev_priv->gt_irq_mask = ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
+ gt_irqs |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
}
gt_irqs |= GT_RENDER_USER_INTERRUPT;
@@ -2831,10 +2306,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
} else {
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
- DE_AUX_CHANNEL_A |
- DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
- DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
- DE_POISON);
+ DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN |
+ DE_PIPEA_FIFO_UNDERRUN | DE_POISON);
extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT;
}
@@ -2868,8 +2341,7 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u32 enable_mask;
- u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV |
- PIPE_CRC_DONE_ENABLE;
+ u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV;
unsigned long irqflags;
enable_mask = I915_DISPLAY_PORT_INTERRUPT;
@@ -2899,9 +2371,9 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
/* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy. */
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable);
- i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_EVENT_ENABLE);
- i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable);
+ i915_enable_pipestat(dev_priv, 0, pipestat_enable);
+ i915_enable_pipestat(dev_priv, 0, PIPE_GMBUS_EVENT_ENABLE);
+ i915_enable_pipestat(dev_priv, 1, pipestat_enable);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
I915_WRITE(VLV_IIR, 0xffffffff);
@@ -2920,117 +2392,6 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
return 0;
}
-static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
-{
- int i;
-
- /* These are interrupts we'll toggle with the ring mask register */
- uint32_t gt_interrupts[] = {
- GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
- GT_RENDER_L3_PARITY_ERROR_INTERRUPT |
- GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT,
- GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT |
- GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT,
- 0,
- GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT
- };
-
- for (i = 0; i < ARRAY_SIZE(gt_interrupts); i++) {
- u32 tmp = I915_READ(GEN8_GT_IIR(i));
- if (tmp)
- DRM_ERROR("Interrupt (%d) should have been masked in pre-install 0x%08x\n",
- i, tmp);
- I915_WRITE(GEN8_GT_IMR(i), ~gt_interrupts[i]);
- I915_WRITE(GEN8_GT_IER(i), gt_interrupts[i]);
- }
- POSTING_READ(GEN8_GT_IER(0));
-}
-
-static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
-{
- struct drm_device *dev = dev_priv->dev;
- uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
- GEN8_PIPE_CDCLK_CRC_DONE |
- GEN8_PIPE_FIFO_UNDERRUN |
- GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
- uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK;
- int pipe;
- dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
- dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
- dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
-
- for_each_pipe(pipe) {
- u32 tmp = I915_READ(GEN8_DE_PIPE_IIR(pipe));
- if (tmp)
- DRM_ERROR("Interrupt (%d) should have been masked in pre-install 0x%08x\n",
- pipe, tmp);
- I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
- I915_WRITE(GEN8_DE_PIPE_IER(pipe), de_pipe_enables);
- }
- POSTING_READ(GEN8_DE_PIPE_ISR(0));
-
- I915_WRITE(GEN8_DE_PORT_IMR, ~GEN8_AUX_CHANNEL_A);
- I915_WRITE(GEN8_DE_PORT_IER, GEN8_AUX_CHANNEL_A);
- POSTING_READ(GEN8_DE_PORT_IER);
-}
-
-static int gen8_irq_postinstall(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- gen8_gt_irq_postinstall(dev_priv);
- gen8_de_irq_postinstall(dev_priv);
-
- ibx_irq_postinstall(dev);
-
- I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL);
- POSTING_READ(GEN8_MASTER_IRQ);
-
- return 0;
-}
-
-static void gen8_irq_uninstall(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int pipe;
-
- if (!dev_priv)
- return;
-
- atomic_set(&dev_priv->irq_received, 0);
-
- I915_WRITE(GEN8_MASTER_IRQ, 0);
-
-#define GEN8_IRQ_FINI_NDX(type, which) do { \
- I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \
- I915_WRITE(GEN8_##type##_IER(which), 0); \
- I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \
- } while (0)
-
-#define GEN8_IRQ_FINI(type) do { \
- I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \
- I915_WRITE(GEN8_##type##_IER, 0); \
- I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \
- } while (0)
-
- GEN8_IRQ_FINI_NDX(GT, 0);
- GEN8_IRQ_FINI_NDX(GT, 1);
- GEN8_IRQ_FINI_NDX(GT, 2);
- GEN8_IRQ_FINI_NDX(GT, 3);
-
- for_each_pipe(pipe) {
- GEN8_IRQ_FINI_NDX(DE_PIPE, pipe);
- }
-
- GEN8_IRQ_FINI(DE_PORT);
- GEN8_IRQ_FINI(DE_MISC);
- GEN8_IRQ_FINI(PCU);
-#undef GEN8_IRQ_FINI
-#undef GEN8_IRQ_FINI_NDX
-
- POSTING_READ(GEN8_PCU_IIR);
-}
-
static void valleyview_irq_uninstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -3103,7 +2464,6 @@ static void i8xx_irq_preinstall(struct drm_device * dev)
static int i8xx_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- unsigned long irqflags;
I915_WRITE16(EMR,
~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH));
@@ -3124,13 +2484,6 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
I915_USER_INTERRUPT);
POSTING_READ16(IER);
- /* Interrupt setup is already guaranteed to be single-threaded, this is
- * just to make the assert_spin_locked check happy. */
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE);
- i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE);
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
-
return 0;
}
@@ -3217,14 +2570,13 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
if (iir & I915_USER_INTERRUPT)
notify_ring(dev, &dev_priv->ring[RCS]);
- for_each_pipe(pipe) {
- if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
- i8xx_handle_vblank(dev, pipe, iir))
- flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
+ if (pipe_stats[0] & PIPE_VBLANK_INTERRUPT_STATUS &&
+ i8xx_handle_vblank(dev, 0, iir))
+ flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(0);
- if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
- i9xx_pipe_crc_irq_handler(dev, pipe);
- }
+ if (pipe_stats[1] & PIPE_VBLANK_INTERRUPT_STATUS &&
+ i8xx_handle_vblank(dev, 1, iir))
+ flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(1);
iir = new_iir;
}
@@ -3271,7 +2623,6 @@ static int i915_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u32 enable_mask;
- unsigned long irqflags;
I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH));
@@ -3307,13 +2658,6 @@ static int i915_irq_postinstall(struct drm_device *dev)
i915_enable_asle_pipestat(dev);
- /* Interrupt setup is already guaranteed to be single-threaded, this is
- * just to make the assert_spin_locked check happy. */
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE);
- i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE);
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
-
return 0;
}
@@ -3425,9 +2769,6 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
-
- if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
- i9xx_pipe_crc_irq_handler(dev, pipe);
}
if (blc_event || (iir & I915_ASLE_INTERRUPT))
@@ -3526,9 +2867,7 @@ static int i965_irq_postinstall(struct drm_device *dev)
/* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy. */
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_EVENT_ENABLE);
- i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE);
- i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE);
+ i915_enable_pipestat(dev_priv, 0, PIPE_GMBUS_EVENT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
/*
@@ -3674,9 +3013,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
-
- if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
- i9xx_pipe_crc_irq_handler(dev, pipe);
}
@@ -3786,21 +3122,18 @@ void intel_irq_init(struct drm_device *dev)
pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
- if (IS_GEN2(dev)) {
- dev->max_vblank_count = 0;
- dev->driver->get_vblank_counter = i8xx_get_vblank_counter;
- } else if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+ dev->driver->get_vblank_counter = i915_get_vblank_counter;
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+ if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
dev->driver->get_vblank_counter = gm45_get_vblank_counter;
- } else {
- dev->driver->get_vblank_counter = i915_get_vblank_counter;
- dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
}
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
- dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
- }
+ else
+ dev->driver->get_vblank_timestamp = NULL;
+ dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
if (IS_VALLEYVIEW(dev)) {
dev->driver->irq_handler = valleyview_irq_handler;
@@ -3810,14 +3143,6 @@ void intel_irq_init(struct drm_device *dev)
dev->driver->enable_vblank = valleyview_enable_vblank;
dev->driver->disable_vblank = valleyview_disable_vblank;
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
- } else if (IS_GEN8(dev)) {
- dev->driver->irq_handler = gen8_irq_handler;
- dev->driver->irq_preinstall = gen8_irq_preinstall;
- dev->driver->irq_postinstall = gen8_irq_postinstall;
- dev->driver->irq_uninstall = gen8_irq_uninstall;
- dev->driver->enable_vblank = gen8_enable_vblank;
- dev->driver->disable_vblank = gen8_disable_vblank;
- dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup;
} else if (HAS_PCH_SPLIT(dev)) {
dev->driver->irq_handler = ironlake_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_preinstall;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ee27421..ef9b354 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -26,7 +26,6 @@
#define _I915_REG_H_
#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
-#define _PIPE_INC(pipe, base, inc) ((base) + (pipe)*(inc))
#define _TRANSCODER(tran, a, b) ((a) + (tran)*((b)-(a)))
#define _PORT(port, a, b) ((a) + (port)*((b)-(a)))
@@ -110,9 +109,6 @@
#define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220)
#define PP_DIR_DCLV_2G 0xffffffff
-#define GEN8_RING_PDP_UDW(ring, n) ((ring)->mmio_base+0x270 + ((n) * 8 + 4))
-#define GEN8_RING_PDP_LDW(ring, n) ((ring)->mmio_base+0x270 + (n) * 8)
-
#define GAM_ECOCHK 0x4090
#define ECOCHK_SNB_BIT (1<<10)
#define HSW_ECOCHK_ARB_PRIO_SOL (1<<6)
@@ -235,7 +231,6 @@
*/
#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1)
#define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*x-1)
-#define MI_SRM_LRM_GLOBAL_GTT (1<<22)
#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */
#define MI_FLUSH_DW_STORE_INDEX (1<<21)
#define MI_INVALIDATE_TLB (1<<18)
@@ -251,7 +246,6 @@
#define MI_BATCH_NON_SECURE_HSW (1<<13)
#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
#define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */
-#define MI_BATCH_BUFFER_START_GEN8 MI_INSTR(0x31, 1)
#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */
#define MI_SEMAPHORE_GLOBAL_GTT (1<<22)
#define MI_SEMAPHORE_UPDATE (1<<21)
@@ -270,11 +264,6 @@
#define MI_SEMAPHORE_SYNC_VVE (1<<16) /* VECS wait for VCS (VEVSYNC) */
#define MI_SEMAPHORE_SYNC_RVE (2<<16) /* VECS wait for RCS (VERSYNC) */
#define MI_SEMAPHORE_SYNC_INVALID (3<<16)
-
-#define MI_PREDICATE_RESULT_2 (0x2214)
-#define LOWER_SLICE_ENABLED (1<<0)
-#define LOWER_SLICE_DISABLED (0<<0)
-
/*
* 3D instructions used by the kernel
*/
@@ -357,25 +346,12 @@
#define IOSF_PORT_PUNIT 0x4
#define IOSF_PORT_NC 0x11
#define IOSF_PORT_DPIO 0x12
-#define IOSF_PORT_GPIO_NC 0x13
-#define IOSF_PORT_CCK 0x14
-#define IOSF_PORT_CCU 0xA9
-#define IOSF_PORT_GPS_CORE 0x48
#define VLV_IOSF_DATA (VLV_DISPLAY_BASE + 0x2104)
#define VLV_IOSF_ADDR (VLV_DISPLAY_BASE + 0x2108)
#define PUNIT_OPCODE_REG_READ 6
#define PUNIT_OPCODE_REG_WRITE 7
-#define PUNIT_REG_PWRGT_CTRL 0x60
-#define PUNIT_REG_PWRGT_STATUS 0x61
-#define PUNIT_CLK_GATE 1
-#define PUNIT_PWR_RESET 2
-#define PUNIT_PWR_GATE 3
-#define RENDER_PWRGT (PUNIT_PWR_GATE << 0)
-#define MEDIA_PWRGT (PUNIT_PWR_GATE << 2)
-#define DISP2D_PWRGT (PUNIT_PWR_GATE << 6)
-
#define PUNIT_REG_GPU_LFM 0xd3
#define PUNIT_REG_GPU_FREQ_REQ 0xd4
#define PUNIT_REG_GPU_FREQ_STS 0xd8
@@ -396,40 +372,6 @@
#define FB_FMAX_VMIN_FREQ_LO_SHIFT 27
#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000
-/* vlv2 north clock has */
-#define CCK_FUSE_REG 0x8
-#define CCK_FUSE_HPLL_FREQ_MASK 0x3
-#define CCK_REG_DSI_PLL_FUSE 0x44
-#define CCK_REG_DSI_PLL_CONTROL 0x48
-#define DSI_PLL_VCO_EN (1 << 31)
-#define DSI_PLL_LDO_GATE (1 << 30)
-#define DSI_PLL_P1_POST_DIV_SHIFT 17
-#define DSI_PLL_P1_POST_DIV_MASK (0x1ff << 17)
-#define DSI_PLL_P2_MUX_DSI0_DIV2 (1 << 13)
-#define DSI_PLL_P3_MUX_DSI1_DIV2 (1 << 12)
-#define DSI_PLL_MUX_MASK (3 << 9)
-#define DSI_PLL_MUX_DSI0_DSIPLL (0 << 10)
-#define DSI_PLL_MUX_DSI0_CCK (1 << 10)
-#define DSI_PLL_MUX_DSI1_DSIPLL (0 << 9)
-#define DSI_PLL_MUX_DSI1_CCK (1 << 9)
-#define DSI_PLL_CLK_GATE_MASK (0xf << 5)
-#define DSI_PLL_CLK_GATE_DSI0_DSIPLL (1 << 8)
-#define DSI_PLL_CLK_GATE_DSI1_DSIPLL (1 << 7)
-#define DSI_PLL_CLK_GATE_DSI0_CCK (1 << 6)
-#define DSI_PLL_CLK_GATE_DSI1_CCK (1 << 5)
-#define DSI_PLL_LOCK (1 << 0)
-#define CCK_REG_DSI_PLL_DIVIDER 0x4c
-#define DSI_PLL_LFSR (1 << 31)
-#define DSI_PLL_FRACTION_EN (1 << 30)
-#define DSI_PLL_FRAC_COUNTER_SHIFT 27
-#define DSI_PLL_FRAC_COUNTER_MASK (7 << 27)
-#define DSI_PLL_USYNC_CNT_SHIFT 18
-#define DSI_PLL_USYNC_CNT_MASK (0x1ff << 18)
-#define DSI_PLL_N1_DIV_SHIFT 16
-#define DSI_PLL_N1_DIV_MASK (3 << 16)
-#define DSI_PLL_M1_DIV_SHIFT 0
-#define DSI_PLL_M1_DIV_MASK (0x1ff << 0)
-
/*
* DPIO - a special bus for various display related registers to hide behind
*
@@ -445,11 +387,11 @@
#define DPIO_MODSEL1 (1<<3) /* if ref clk b == 27 */
#define DPIO_MODSEL0 (1<<2) /* if ref clk a == 27 */
#define DPIO_SFR_BYPASS (1<<1)
-#define DPIO_CMNRST (1<<0)
+#define DPIO_RESET (1<<0)
#define _DPIO_TX3_SWING_CTL4_A 0x690
#define _DPIO_TX3_SWING_CTL4_B 0x2a90
-#define DPIO_TX3_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX3_SWING_CTL4_A, \
+#define DPIO_TX3_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL4_A, \
_DPIO_TX3_SWING_CTL4_B)
/*
@@ -660,9 +602,6 @@
#define ARB_MODE 0x04030
#define ARB_MODE_SWIZZLE_SNB (1<<4)
#define ARB_MODE_SWIZZLE_IVB (1<<5)
-#define GAMTARBMODE 0x04a08
-#define ARB_MODE_BWGTLB_DISABLE (1<<9)
-#define ARB_MODE_SWIZZLE_BDW (1<<1)
#define RENDER_HWS_PGA_GEN7 (0x04080)
#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id)
#define RING_FAULT_GTTSEL_MASK (1<<11)
@@ -670,7 +609,6 @@
#define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3)
#define RING_FAULT_VALID (1<<0)
#define DONE_REG 0x40b0
-#define GEN8_PRIVATE_PAT 0x40e0
#define BSD_HWS_PGA_GEN7 (0x04180)
#define BLT_HWS_PGA_GEN7 (0x04280)
#define VEBOX_HWS_PGA_GEN7 (0x04380)
@@ -731,18 +669,13 @@
#define NOPID 0x02094
#define HWSTAM 0x02098
#define DMA_FADD_I8XX 0x020d0
-#define RING_BBSTATE(base) ((base)+0x110)
#define ERROR_GEN6 0x040a0
#define GEN7_ERR_INT 0x44040
#define ERR_INT_POISON (1<<31)
#define ERR_INT_MMIO_UNCLAIMED (1<<13)
-#define ERR_INT_PIPE_CRC_DONE_C (1<<8)
#define ERR_INT_FIFO_UNDERRUN_C (1<<6)
-#define ERR_INT_PIPE_CRC_DONE_B (1<<5)
#define ERR_INT_FIFO_UNDERRUN_B (1<<3)
-#define ERR_INT_PIPE_CRC_DONE_A (1<<2)
-#define ERR_INT_PIPE_CRC_DONE(pipe) (1<<(2 + pipe*3))
#define ERR_INT_FIFO_UNDERRUN_A (1<<0)
#define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3))
@@ -750,7 +683,6 @@
#define FPGA_DBG_RM_NOCLAIM (1<<31)
#define DERRMR 0x44050
-/* Note that HBLANK events are reserved on bdw+ */
#define DERRMR_PIPEA_SCANLINE (1<<0)
#define DERRMR_PIPEA_PRI_FLIP_DONE (1<<1)
#define DERRMR_PIPEA_SPR_FLIP_DONE (1<<2)
@@ -784,7 +716,6 @@
#define _3D_CHICKEN3 0x02090
#define _3D_CHICKEN_SF_DISABLE_OBJEND_CULL (1 << 10)
#define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5)
-#define _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(x) ((x)<<1)
#define MI_MODE 0x0209c
# define VS_TIMER_DISPATCH (1 << 6)
@@ -959,7 +890,6 @@
#define GT_BLT_USER_INTERRUPT (1 << 22)
#define GT_BSD_CS_ERROR_INTERRUPT (1 << 15)
#define GT_BSD_USER_INTERRUPT (1 << 12)
-#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 (1 << 11) /* hsw+; rsvd on snb, ivb, vlv */
#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT (1 << 5) /* !snb */
#define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT (1 << 4)
#define GT_RENDER_CS_MASTER_ERROR_INTERRUPT (1 << 3)
@@ -970,10 +900,6 @@
#define PM_VEBOX_CS_ERROR_INTERRUPT (1 << 12) /* hsw+ */
#define PM_VEBOX_USER_INTERRUPT (1 << 10) /* hsw+ */
-#define GT_PARITY_ERROR(dev) \
- (GT_RENDER_L3_PARITY_ERROR_INTERRUPT | \
- (IS_HASWELL(dev) ? GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 : 0))
-
/* These are all the "old" interrupts */
#define ILK_BSD_USER_INTERRUPT (1<<5)
#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
@@ -1122,6 +1048,9 @@
_HSW_PIPE_SLICE_CHICKEN_1_A, + \
_HSW_PIPE_SLICE_CHICKEN_1_B)
+#define HSW_CLKGATE_DISABLE_PART_1 0x46500
+#define HSW_DPFC_GATING_DISABLE (1<<23)
+
/*
* GPIO regs
*/
@@ -1458,12 +1387,6 @@
#define MI_ARB_VLV (VLV_DISPLAY_BASE + 0x6504)
-#define CZCLK_CDCLK_FREQ_RATIO (VLV_DISPLAY_BASE + 0x6508)
-#define CDCLK_FREQ_SHIFT 4
-#define CDCLK_FREQ_MASK (0x1f << CDCLK_FREQ_SHIFT)
-#define CZCLK_FREQ_MASK 0xf
-#define GMBUSFREQ_VLV (VLV_DISPLAY_BASE + 0x6510)
-
/*
* Palette regs
*/
@@ -1481,15 +1404,13 @@
* device 0 function 0's pci config register 0x44 or 0x48 and matches it in
* every way. It is not accessible from the CP register read instructions.
*
- * Starting from Haswell, you can't write registers using the MCHBAR mirror,
- * just read.
*/
#define MCHBAR_MIRROR_BASE 0x10000
#define MCHBAR_MIRROR_BASE_SNB 0x140000
/* Memory controller frequency in MCHBAR for Haswell (possible SNB+) */
-#define DCLK (MCHBAR_MIRROR_BASE_SNB + 0x5e04)
+#define DCLK 0x5e04
/** 915-945 and GM965 MCH register controlling DRAM channel access */
#define DCC 0x10200
@@ -1784,9 +1705,9 @@
#define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7
#define GEN6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16))
-#define GEN6_GT_PERF_STATUS (MCHBAR_MIRROR_BASE_SNB + 0x5948)
-#define GEN6_RP_STATE_LIMITS (MCHBAR_MIRROR_BASE_SNB + 0x5994)
-#define GEN6_RP_STATE_CAP (MCHBAR_MIRROR_BASE_SNB + 0x5998)
+#define GEN6_GT_PERF_STATUS 0x145948
+#define GEN6_RP_STATE_LIMITS 0x145994
+#define GEN6_RP_STATE_CAP 0x145998
/*
* Logical Context regs
@@ -1831,12 +1752,6 @@
* on HSW) - so the final size is 66944 bytes, which rounds to 17 pages.
*/
#define HSW_CXT_TOTAL_SIZE (17 * PAGE_SIZE)
-/* Same as Haswell, but 72064 bytes now. */
-#define GEN8_CXT_TOTAL_SIZE (18 * PAGE_SIZE)
-
-
-#define VLV_CLK_CTL2 0x101104
-#define CLK_CTL2_CZCOUNT_30NS_SHIFT 28
/*
* Overlay regs
@@ -1856,83 +1771,6 @@
* Display engine regs
*/
-/* Pipe A CRC regs */
-#define _PIPE_CRC_CTL_A (dev_priv->info->display_mmio_offset + 0x60050)
-#define PIPE_CRC_ENABLE (1 << 31)
-/* ivb+ source selection */
-#define PIPE_CRC_SOURCE_PRIMARY_IVB (0 << 29)
-#define PIPE_CRC_SOURCE_SPRITE_IVB (1 << 29)
-#define PIPE_CRC_SOURCE_PF_IVB (2 << 29)
-/* ilk+ source selection */
-#define PIPE_CRC_SOURCE_PRIMARY_ILK (0 << 28)
-#define PIPE_CRC_SOURCE_SPRITE_ILK (1 << 28)
-#define PIPE_CRC_SOURCE_PIPE_ILK (2 << 28)
-/* embedded DP port on the north display block, reserved on ivb */
-#define PIPE_CRC_SOURCE_PORT_A_ILK (4 << 28)
-#define PIPE_CRC_SOURCE_FDI_ILK (5 << 28) /* reserved on ivb */
-/* vlv source selection */
-#define PIPE_CRC_SOURCE_PIPE_VLV (0 << 27)
-#define PIPE_CRC_SOURCE_HDMIB_VLV (1 << 27)
-#define PIPE_CRC_SOURCE_HDMIC_VLV (2 << 27)
-/* with DP port the pipe source is invalid */
-#define PIPE_CRC_SOURCE_DP_D_VLV (3 << 27)
-#define PIPE_CRC_SOURCE_DP_B_VLV (6 << 27)
-#define PIPE_CRC_SOURCE_DP_C_VLV (7 << 27)
-/* gen3+ source selection */
-#define PIPE_CRC_SOURCE_PIPE_I9XX (0 << 28)
-#define PIPE_CRC_SOURCE_SDVOB_I9XX (1 << 28)
-#define PIPE_CRC_SOURCE_SDVOC_I9XX (2 << 28)
-/* with DP/TV port the pipe source is invalid */
-#define PIPE_CRC_SOURCE_DP_D_G4X (3 << 28)
-#define PIPE_CRC_SOURCE_TV_PRE (4 << 28)
-#define PIPE_CRC_SOURCE_TV_POST (5 << 28)
-#define PIPE_CRC_SOURCE_DP_B_G4X (6 << 28)
-#define PIPE_CRC_SOURCE_DP_C_G4X (7 << 28)
-/* gen2 doesn't have source selection bits */
-#define PIPE_CRC_INCLUDE_BORDER_I8XX (1 << 30)
-
-#define _PIPE_CRC_RES_1_A_IVB 0x60064
-#define _PIPE_CRC_RES_2_A_IVB 0x60068
-#define _PIPE_CRC_RES_3_A_IVB 0x6006c
-#define _PIPE_CRC_RES_4_A_IVB 0x60070
-#define _PIPE_CRC_RES_5_A_IVB 0x60074
-
-#define _PIPE_CRC_RES_RED_A (dev_priv->info->display_mmio_offset + 0x60060)
-#define _PIPE_CRC_RES_GREEN_A (dev_priv->info->display_mmio_offset + 0x60064)
-#define _PIPE_CRC_RES_BLUE_A (dev_priv->info->display_mmio_offset + 0x60068)
-#define _PIPE_CRC_RES_RES1_A_I915 (dev_priv->info->display_mmio_offset + 0x6006c)
-#define _PIPE_CRC_RES_RES2_A_G4X (dev_priv->info->display_mmio_offset + 0x60080)
-
-/* Pipe B CRC regs */
-#define _PIPE_CRC_RES_1_B_IVB 0x61064
-#define _PIPE_CRC_RES_2_B_IVB 0x61068
-#define _PIPE_CRC_RES_3_B_IVB 0x6106c
-#define _PIPE_CRC_RES_4_B_IVB 0x61070
-#define _PIPE_CRC_RES_5_B_IVB 0x61074
-
-#define PIPE_CRC_CTL(pipe) _PIPE_INC(pipe, _PIPE_CRC_CTL_A, 0x01000)
-#define PIPE_CRC_RES_1_IVB(pipe) \
- _PIPE(pipe, _PIPE_CRC_RES_1_A_IVB, _PIPE_CRC_RES_1_B_IVB)
-#define PIPE_CRC_RES_2_IVB(pipe) \
- _PIPE(pipe, _PIPE_CRC_RES_2_A_IVB, _PIPE_CRC_RES_2_B_IVB)
-#define PIPE_CRC_RES_3_IVB(pipe) \
- _PIPE(pipe, _PIPE_CRC_RES_3_A_IVB, _PIPE_CRC_RES_3_B_IVB)
-#define PIPE_CRC_RES_4_IVB(pipe) \
- _PIPE(pipe, _PIPE_CRC_RES_4_A_IVB, _PIPE_CRC_RES_4_B_IVB)
-#define PIPE_CRC_RES_5_IVB(pipe) \
- _PIPE(pipe, _PIPE_CRC_RES_5_A_IVB, _PIPE_CRC_RES_5_B_IVB)
-
-#define PIPE_CRC_RES_RED(pipe) \
- _PIPE_INC(pipe, _PIPE_CRC_RES_RED_A, 0x01000)
-#define PIPE_CRC_RES_GREEN(pipe) \
- _PIPE_INC(pipe, _PIPE_CRC_RES_GREEN_A, 0x01000)
-#define PIPE_CRC_RES_BLUE(pipe) \
- _PIPE_INC(pipe, _PIPE_CRC_RES_BLUE_A, 0x01000)
-#define PIPE_CRC_RES_RES1_I915(pipe) \
- _PIPE_INC(pipe, _PIPE_CRC_RES_RES1_A_I915, 0x01000)
-#define PIPE_CRC_RES_RES2_G4X(pipe) \
- _PIPE_INC(pipe, _PIPE_CRC_RES_RES2_A_G4X, 0x01000)
-
/* Pipe A timing regs */
#define _HTOTAL_A (dev_priv->info->display_mmio_offset + 0x60000)
#define _HBLANK_A (dev_priv->info->display_mmio_offset + 0x60004)
@@ -1955,6 +1793,7 @@
#define _BCLRPAT_B (dev_priv->info->display_mmio_offset + 0x61020)
#define _VSYNCSHIFT_B (dev_priv->info->display_mmio_offset + 0x61028)
+
#define HTOTAL(trans) _TRANSCODER(trans, _HTOTAL_A, _HTOTAL_B)
#define HBLANK(trans) _TRANSCODER(trans, _HBLANK_A, _HBLANK_B)
#define HSYNC(trans) _TRANSCODER(trans, _HSYNC_A, _HSYNC_B)
@@ -1964,9 +1803,8 @@
#define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B)
#define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B)
-/* HSW+ eDP PSR registers */
-#define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800)
-#define EDP_PSR_CTL(dev) (EDP_PSR_BASE(dev) + 0)
+/* HSW eDP PSR registers */
+#define EDP_PSR_CTL 0x64800
#define EDP_PSR_ENABLE (1<<31)
#define EDP_PSR_LINK_DISABLE (0<<27)
#define EDP_PSR_LINK_STANDBY (1<<27)
@@ -1989,16 +1827,16 @@
#define EDP_PSR_TP1_TIME_0us (3<<4)
#define EDP_PSR_IDLE_FRAME_SHIFT 0
-#define EDP_PSR_AUX_CTL(dev) (EDP_PSR_BASE(dev) + 0x10)
-#define EDP_PSR_AUX_DATA1(dev) (EDP_PSR_BASE(dev) + 0x14)
+#define EDP_PSR_AUX_CTL 0x64810
+#define EDP_PSR_AUX_DATA1 0x64814
#define EDP_PSR_DPCD_COMMAND 0x80060000
-#define EDP_PSR_AUX_DATA2(dev) (EDP_PSR_BASE(dev) + 0x18)
+#define EDP_PSR_AUX_DATA2 0x64818
#define EDP_PSR_DPCD_NORMAL_OPERATION (1<<24)
-#define EDP_PSR_AUX_DATA3(dev) (EDP_PSR_BASE(dev) + 0x1c)
-#define EDP_PSR_AUX_DATA4(dev) (EDP_PSR_BASE(dev) + 0x20)
-#define EDP_PSR_AUX_DATA5(dev) (EDP_PSR_BASE(dev) + 0x24)
+#define EDP_PSR_AUX_DATA3 0x6481c
+#define EDP_PSR_AUX_DATA4 0x64820
+#define EDP_PSR_AUX_DATA5 0x64824
-#define EDP_PSR_STATUS_CTL(dev) (EDP_PSR_BASE(dev) + 0x40)
+#define EDP_PSR_STATUS_CTL 0x64840
#define EDP_PSR_STATUS_STATE_MASK (7<<29)
#define EDP_PSR_STATUS_STATE_IDLE (0<<29)
#define EDP_PSR_STATUS_STATE_SRDONACK (1<<29)
@@ -2022,10 +1860,10 @@
#define EDP_PSR_STATUS_SENDING_TP1 (1<<4)
#define EDP_PSR_STATUS_IDLE_MASK 0xf
-#define EDP_PSR_PERF_CNT(dev) (EDP_PSR_BASE(dev) + 0x44)
+#define EDP_PSR_PERF_CNT 0x64844
#define EDP_PSR_PERF_CNT_MASK 0xffffff
-#define EDP_PSR_DEBUG_CTL(dev) (EDP_PSR_BASE(dev) + 0x60)
+#define EDP_PSR_DEBUG_CTL 0x64860
#define EDP_PSR_DEBUG_MASK_LPSP (1<<27)
#define EDP_PSR_DEBUG_MASK_MEMUP (1<<26)
#define EDP_PSR_DEBUG_MASK_HPD (1<<25)
@@ -2168,14 +2006,6 @@
#define PCH_HDMIC 0xe1150
#define PCH_HDMID 0xe1160
-#define PORT_DFT_I9XX 0x61150
-#define DC_BALANCE_RESET (1 << 25)
-#define PORT_DFT2_G4X 0x61154
-#define DC_BALANCE_RESET_VLV (1 << 31)
-#define PIPE_SCRAMBLE_RESET_MASK (0x3 << 0)
-#define PIPE_B_SCRAMBLE_RESET (1 << 1)
-#define PIPE_A_SCRAMBLE_RESET (1 << 0)
-
/* Gen 3 SDVO bits: */
#define SDVO_ENABLE (1 << 31)
#define SDVO_PIPE_SEL(pipe) ((pipe) << 30)
@@ -2204,7 +2034,6 @@
/* Gen 4 SDVO/HDMI bits: */
#define SDVO_COLOR_FORMAT_8bpc (0 << 26)
-#define SDVO_COLOR_FORMAT_MASK (7 << 26)
#define SDVO_ENCODING_SDVO (0 << 10)
#define SDVO_ENCODING_HDMI (2 << 10)
#define HDMI_MODE_SELECT_HDMI (1 << 9) /* HDMI only */
@@ -2409,21 +2238,6 @@
#define PFIT_AUTO_RATIOS (dev_priv->info->display_mmio_offset + 0x61238)
-#define _VLV_BLC_PWM_CTL2_A (dev_priv->info->display_mmio_offset + 0x61250)
-#define _VLV_BLC_PWM_CTL2_B (dev_priv->info->display_mmio_offset + 0x61350)
-#define VLV_BLC_PWM_CTL2(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL2_A, \
- _VLV_BLC_PWM_CTL2_B)
-
-#define _VLV_BLC_PWM_CTL_A (dev_priv->info->display_mmio_offset + 0x61254)
-#define _VLV_BLC_PWM_CTL_B (dev_priv->info->display_mmio_offset + 0x61354)
-#define VLV_BLC_PWM_CTL(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL_A, \
- _VLV_BLC_PWM_CTL_B)
-
-#define _VLV_BLC_HIST_CTL_A (dev_priv->info->display_mmio_offset + 0x61260)
-#define _VLV_BLC_HIST_CTL_B (dev_priv->info->display_mmio_offset + 0x61360)
-#define VLV_BLC_HIST_CTL(pipe) _PIPE(pipe, _VLV_BLC_HIST_CTL_A, \
- _VLV_BLC_HIST_CTL_B)
-
/* Backlight control */
#define BLC_PWM_CTL2 (dev_priv->info->display_mmio_offset + 0x61250) /* 965+ only */
#define BLM_PWM_ENABLE (1 << 31)
@@ -3172,7 +2986,6 @@
#define PIPECONF_DISABLE 0
#define PIPECONF_DOUBLE_WIDE (1<<30)
#define I965_PIPECONF_ACTIVE (1<<30)
-#define PIPECONF_DSI_PLL_LOCKED (1<<29) /* vlv & pipe A only */
#define PIPECONF_FRAME_START_DELAY_MASK (3<<27)
#define PIPECONF_SINGLE_WIDE 0
#define PIPECONF_PIPE_UNLOCKED 0
@@ -3255,18 +3068,6 @@
#define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL)
#define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT)
-#define _PIPE_MISC_A 0x70030
-#define _PIPE_MISC_B 0x71030
-#define PIPEMISC_DITHER_BPC_MASK (7<<5)
-#define PIPEMISC_DITHER_8_BPC (0<<5)
-#define PIPEMISC_DITHER_10_BPC (1<<5)
-#define PIPEMISC_DITHER_6_BPC (2<<5)
-#define PIPEMISC_DITHER_12_BPC (3<<5)
-#define PIPEMISC_DITHER_ENABLE (1<<4)
-#define PIPEMISC_DITHER_TYPE_MASK (3<<2)
-#define PIPEMISC_DITHER_TYPE_SP (0<<2)
-#define PIPEMISC(pipe) _PIPE(pipe, _PIPE_MISC_A, _PIPE_MISC_B)
-
#define VLV_DPFLIPSTAT (VLV_DISPLAY_BASE + 0x70028)
#define PIPEB_LINE_COMPARE_INT_EN (1<<29)
#define PIPEB_HLINE_INT_EN (1<<28)
@@ -3383,11 +3184,11 @@
/* define the Watermark register on Ironlake */
#define WM0_PIPEA_ILK 0x45100
-#define WM0_PIPE_PLANE_MASK (0xffff<<16)
+#define WM0_PIPE_PLANE_MASK (0x7f<<16)
#define WM0_PIPE_PLANE_SHIFT 16
-#define WM0_PIPE_SPRITE_MASK (0xff<<8)
+#define WM0_PIPE_SPRITE_MASK (0x3f<<8)
#define WM0_PIPE_SPRITE_SHIFT 8
-#define WM0_PIPE_CURSOR_MASK (0xff)
+#define WM0_PIPE_CURSOR_MASK (0x1f)
#define WM0_PIPEB_ILK 0x45104
#define WM0_PIPEC_IVB 0x45200
@@ -3397,10 +3198,9 @@
#define WM1_LP_LATENCY_MASK (0x7f<<24)
#define WM1_LP_FBC_MASK (0xf<<20)
#define WM1_LP_FBC_SHIFT 20
-#define WM1_LP_FBC_SHIFT_BDW 19
-#define WM1_LP_SR_MASK (0x7ff<<8)
+#define WM1_LP_SR_MASK (0x1ff<<8)
#define WM1_LP_SR_SHIFT 8
-#define WM1_LP_CURSOR_MASK (0xff)
+#define WM1_LP_CURSOR_MASK (0x3f)
#define WM2_LP_ILK 0x4510c
#define WM2_LP_EN (1<<31)
#define WM3_LP_ILK 0x45110
@@ -3481,17 +3281,17 @@
* } while (high1 != high2);
* frame = (high1 << 8) | low1;
*/
-#define _PIPEAFRAMEHIGH 0x70040
+#define _PIPEAFRAMEHIGH (dev_priv->info->display_mmio_offset + 0x70040)
#define PIPE_FRAME_HIGH_MASK 0x0000ffff
#define PIPE_FRAME_HIGH_SHIFT 0
-#define _PIPEAFRAMEPIXEL 0x70044
+#define _PIPEAFRAMEPIXEL (dev_priv->info->display_mmio_offset + 0x70044)
#define PIPE_FRAME_LOW_MASK 0xff000000
#define PIPE_FRAME_LOW_SHIFT 24
#define PIPE_PIXEL_MASK 0x00ffffff
#define PIPE_PIXEL_SHIFT 0
/* GM45+ just has to be different */
-#define _PIPEA_FRMCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x70040)
-#define _PIPEA_FLIPCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x70044)
+#define _PIPEA_FRMCOUNT_GM45 0x70040
+#define _PIPEA_FLIPCOUNT_GM45 0x70044
#define PIPE_FRMCOUNT_GM45(pipe) _PIPE(pipe, _PIPEA_FRMCOUNT_GM45, _PIPEB_FRMCOUNT_GM45)
/* Cursor A & B regs */
@@ -3622,10 +3422,10 @@
#define _PIPEBDSL (dev_priv->info->display_mmio_offset + 0x71000)
#define _PIPEBCONF (dev_priv->info->display_mmio_offset + 0x71008)
#define _PIPEBSTAT (dev_priv->info->display_mmio_offset + 0x71024)
-#define _PIPEBFRAMEHIGH 0x71040
-#define _PIPEBFRAMEPIXEL 0x71044
-#define _PIPEB_FRMCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x71040)
-#define _PIPEB_FLIPCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x71044)
+#define _PIPEBFRAMEHIGH (dev_priv->info->display_mmio_offset + 0x71040)
+#define _PIPEBFRAMEPIXEL (dev_priv->info->display_mmio_offset + 0x71044)
+#define _PIPEB_FRMCOUNT_GM45 0x71040
+#define _PIPEB_FLIPCOUNT_GM45 0x71044
/* Display B control */
@@ -3980,7 +3780,6 @@
#define DE_SPRITEA_FLIP_DONE (1 << 28)
#define DE_PLANEB_FLIP_DONE (1 << 27)
#define DE_PLANEA_FLIP_DONE (1 << 26)
-#define DE_PLANE_FLIP_DONE(plane) (1 << (26 + (plane)))
#define DE_PCU_EVENT (1 << 25)
#define DE_GTT_FAULT (1 << 24)
#define DE_POISON (1 << 23)
@@ -3994,18 +3793,13 @@
#define DE_PIPEB_ODD_FIELD (1 << 13)
#define DE_PIPEB_LINE_COMPARE (1 << 12)
#define DE_PIPEB_VSYNC (1 << 11)
-#define DE_PIPEB_CRC_DONE (1 << 10)
#define DE_PIPEB_FIFO_UNDERRUN (1 << 8)
#define DE_PIPEA_VBLANK (1 << 7)
-#define DE_PIPE_VBLANK(pipe) (1 << (7 + 8*(pipe)))
#define DE_PIPEA_EVEN_FIELD (1 << 6)
#define DE_PIPEA_ODD_FIELD (1 << 5)
#define DE_PIPEA_LINE_COMPARE (1 << 4)
#define DE_PIPEA_VSYNC (1 << 3)
-#define DE_PIPEA_CRC_DONE (1 << 2)
-#define DE_PIPE_CRC_DONE(pipe) (1 << (2 + 8*(pipe)))
#define DE_PIPEA_FIFO_UNDERRUN (1 << 0)
-#define DE_PIPE_FIFO_UNDERRUN(pipe) (1 << (8*(pipe)))
/* More Ivybridge lolz */
#define DE_ERR_INT_IVB (1<<30)
@@ -4021,8 +3815,9 @@
#define DE_PIPEB_VBLANK_IVB (1<<5)
#define DE_SPRITEA_FLIP_DONE_IVB (1<<4)
#define DE_PLANEA_FLIP_DONE_IVB (1<<3)
-#define DE_PLANE_FLIP_DONE_IVB(plane) (1<< (3 + 5*(plane)))
#define DE_PIPEA_VBLANK_IVB (1<<0)
+
+#define DE_PIPE_VBLANK_ILK(pipe) (1 << ((pipe * 8) + 7))
#define DE_PIPE_VBLANK_IVB(pipe) (1 << (pipe * 5))
#define VLV_MASTER_IER 0x4400c /* Gunit master IER */
@@ -4038,71 +3833,6 @@
#define GTIIR 0x44018
#define GTIER 0x4401c
-#define GEN8_MASTER_IRQ 0x44200
-#define GEN8_MASTER_IRQ_CONTROL (1<<31)
-#define GEN8_PCU_IRQ (1<<30)
-#define GEN8_DE_PCH_IRQ (1<<23)
-#define GEN8_DE_MISC_IRQ (1<<22)
-#define GEN8_DE_PORT_IRQ (1<<20)
-#define GEN8_DE_PIPE_C_IRQ (1<<18)
-#define GEN8_DE_PIPE_B_IRQ (1<<17)
-#define GEN8_DE_PIPE_A_IRQ (1<<16)
-#define GEN8_DE_PIPE_IRQ(pipe) (1<<(16+pipe))
-#define GEN8_GT_VECS_IRQ (1<<6)
-#define GEN8_GT_VCS2_IRQ (1<<3)
-#define GEN8_GT_VCS1_IRQ (1<<2)
-#define GEN8_GT_BCS_IRQ (1<<1)
-#define GEN8_GT_RCS_IRQ (1<<0)
-
-#define GEN8_GT_ISR(which) (0x44300 + (0x10 * (which)))
-#define GEN8_GT_IMR(which) (0x44304 + (0x10 * (which)))
-#define GEN8_GT_IIR(which) (0x44308 + (0x10 * (which)))
-#define GEN8_GT_IER(which) (0x4430c + (0x10 * (which)))
-
-#define GEN8_BCS_IRQ_SHIFT 16
-#define GEN8_RCS_IRQ_SHIFT 0
-#define GEN8_VCS2_IRQ_SHIFT 16
-#define GEN8_VCS1_IRQ_SHIFT 0
-#define GEN8_VECS_IRQ_SHIFT 0
-
-#define GEN8_DE_PIPE_ISR(pipe) (0x44400 + (0x10 * (pipe)))
-#define GEN8_DE_PIPE_IMR(pipe) (0x44404 + (0x10 * (pipe)))
-#define GEN8_DE_PIPE_IIR(pipe) (0x44408 + (0x10 * (pipe)))
-#define GEN8_DE_PIPE_IER(pipe) (0x4440c + (0x10 * (pipe)))
-#define GEN8_PIPE_FIFO_UNDERRUN (1 << 31)
-#define GEN8_PIPE_CDCLK_CRC_ERROR (1 << 29)
-#define GEN8_PIPE_CDCLK_CRC_DONE (1 << 28)
-#define GEN8_PIPE_CURSOR_FAULT (1 << 10)
-#define GEN8_PIPE_SPRITE_FAULT (1 << 9)
-#define GEN8_PIPE_PRIMARY_FAULT (1 << 8)
-#define GEN8_PIPE_SPRITE_FLIP_DONE (1 << 5)
-#define GEN8_PIPE_FLIP_DONE (1 << 4)
-#define GEN8_PIPE_SCAN_LINE_EVENT (1 << 2)
-#define GEN8_PIPE_VSYNC (1 << 1)
-#define GEN8_PIPE_VBLANK (1 << 0)
-#define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \
- (GEN8_PIPE_CURSOR_FAULT | \
- GEN8_PIPE_SPRITE_FAULT | \
- GEN8_PIPE_PRIMARY_FAULT)
-
-#define GEN8_DE_PORT_ISR 0x44440
-#define GEN8_DE_PORT_IMR 0x44444
-#define GEN8_DE_PORT_IIR 0x44448
-#define GEN8_DE_PORT_IER 0x4444c
-#define GEN8_PORT_DP_A_HOTPLUG (1 << 3)
-#define GEN8_AUX_CHANNEL_A (1 << 0)
-
-#define GEN8_DE_MISC_ISR 0x44460
-#define GEN8_DE_MISC_IMR 0x44464
-#define GEN8_DE_MISC_IIR 0x44468
-#define GEN8_DE_MISC_IER 0x4446c
-#define GEN8_DE_MISC_GSE (1 << 27)
-
-#define GEN8_PCU_ISR 0x444e0
-#define GEN8_PCU_IMR 0x444e4
-#define GEN8_PCU_IIR 0x444e8
-#define GEN8_PCU_IER 0x444ec
-
#define ILK_DISPLAY_CHICKEN2 0x42004
/* Required on all Ironlake and Sandybridge according to the B-Spec. */
#define ILK_ELPIN_409_SELECT (1 << 25)
@@ -4128,14 +3858,8 @@
# define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2)
#define CHICKEN_PAR1_1 0x42080
-#define DPA_MASK_VBLANK_SRD (1 << 15)
#define FORCE_ARB_IDLE_PLANES (1 << 14)
-#define _CHICKEN_PIPESL_1_A 0x420b0
-#define _CHICKEN_PIPESL_1_B 0x420b4
-#define DPRS_MASK_VBLANK_SRD (1 << 0)
-#define CHICKEN_PIPESL_1(pipe) _PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B)
-
#define DISP_ARB_CTL 0x45000
#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
#define DISP_FBC_WM_DIS (1<<15)
@@ -4146,8 +3870,6 @@
/* GEN7 chicken */
#define GEN7_COMMON_SLICE_CHICKEN1 0x7010
# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26))
-#define COMMON_SLICE_CHICKEN2 0x7014
-# define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1<<0)
#define GEN7_L3CNTLREG1 0xB01C
#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C
@@ -4694,8 +4416,6 @@
#define PIPEA_PP_STATUS (VLV_DISPLAY_BASE + 0x61200)
#define PIPEA_PP_CONTROL (VLV_DISPLAY_BASE + 0x61204)
#define PIPEA_PP_ON_DELAYS (VLV_DISPLAY_BASE + 0x61208)
-#define PANEL_PORT_SELECT_DPB_VLV (1 << 30)
-#define PANEL_PORT_SELECT_DPC_VLV (2 << 30)
#define PIPEA_PP_OFF_DELAYS (VLV_DISPLAY_BASE + 0x6120c)
#define PIPEA_PP_DIVISOR (VLV_DISPLAY_BASE + 0x61210)
@@ -4727,6 +4447,7 @@
#define PANEL_PORT_SELECT_MASK (3 << 30)
#define PANEL_PORT_SELECT_LVDS (0 << 30)
#define PANEL_PORT_SELECT_DPA (1 << 30)
+#define EDP_PANEL (1 << 30)
#define PANEL_PORT_SELECT_DPC (2 << 30)
#define PANEL_PORT_SELECT_DPD (3 << 30)
#define PANEL_POWER_UP_DELAY_MASK (0x1fff0000)
@@ -4735,6 +4456,11 @@
#define PANEL_LIGHT_ON_DELAY_SHIFT 0
#define PCH_PP_OFF_DELAYS 0xc720c
+#define PANEL_POWER_PORT_SELECT_MASK (0x3 << 30)
+#define PANEL_POWER_PORT_LVDS (0 << 30)
+#define PANEL_POWER_PORT_DP_A (1 << 30)
+#define PANEL_POWER_PORT_DP_C (2 << 30)
+#define PANEL_POWER_PORT_DP_D (3 << 30)
#define PANEL_POWER_DOWN_DELAY_MASK (0x1fff0000)
#define PANEL_POWER_DOWN_DELAY_SHIFT 16
#define PANEL_LIGHT_OFF_DELAY_MASK (0x1fff)
@@ -4912,7 +4638,7 @@
#define GEN6_RP_UP_IDLE_MIN (0x1<<3)
#define GEN6_RP_UP_BUSY_AVG (0x2<<3)
#define GEN6_RP_UP_BUSY_CONT (0x4<<3)
-#define GEN6_RP_DOWN_IDLE_AVG (0x2<<0)
+#define GEN7_RP_DOWN_IDLE_AVG (0x2<<0)
#define GEN6_RP_DOWN_IDLE_CONT (0x1<<0)
#define GEN6_RP_UP_THRESHOLD 0xA02C
#define GEN6_RP_DOWN_THRESHOLD 0xA030
@@ -4957,10 +4683,6 @@
GEN6_PM_RP_DOWN_TIMEOUT)
#define GEN6_GT_GFX_RC6_LOCKED 0x138104
-#define VLV_COUNTER_CONTROL 0x138104
-#define VLV_COUNT_RANGE_HIGH (1<<15)
-#define VLV_MEDIA_RC6_COUNT_EN (1<<1)
-#define VLV_RENDER_RC6_COUNT_EN (1<<0)
#define GEN6_GT_GFX_RC6 0x138108
#define GEN6_GT_GFX_RC6p 0x13810C
#define GEN6_GT_GFX_RC6pp 0x138110
@@ -4972,11 +4694,8 @@
#define GEN6_PCODE_READ_MIN_FREQ_TABLE 0x9
#define GEN6_PCODE_WRITE_RC6VIDS 0x4
#define GEN6_PCODE_READ_RC6VIDS 0x5
-#define GEN6_PCODE_READ_D_COMP 0x10
-#define GEN6_PCODE_WRITE_D_COMP 0x11
#define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5)
#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245)
-#define DISPLAY_IPS_CONTROL 0x19
#define GEN6_PCODE_DATA 0x138128
#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
#define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16
@@ -4994,7 +4713,6 @@
/* IVYBRIDGE DPF */
#define GEN7_L3CDERRST1 0xB008 /* L3CD Error Status 1 */
-#define HSW_L3CDERRST11 0xB208 /* L3CD Error Status register 1 slice 1 */
#define GEN7_L3CDERRST1_ROW_MASK (0x7ff<<14)
#define GEN7_PARITY_ERROR_VALID (1<<13)
#define GEN7_L3CDERRST1_BANK_MASK (3<<11)
@@ -5008,13 +4726,11 @@
#define GEN7_L3CDERRST1_ENABLE (1<<7)
#define GEN7_L3LOG_BASE 0xB070
-#define HSW_L3LOG_BASE_SLICE1 0xB270
#define GEN7_L3LOG_SIZE 0x80
#define GEN7_HALF_SLICE_CHICKEN1 0xe100 /* IVB GT1 + VLV */
#define GEN7_HALF_SLICE_CHICKEN1_GT2 0xf100
#define GEN7_MAX_PS_THREAD_DEP (8<<12)
-#define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10)
#define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3)
#define GEN7_ROW_CHICKEN2 0xe4f4
@@ -5024,10 +4740,6 @@
#define HSW_ROW_CHICKEN3 0xe49c
#define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6)
-#define HALF_SLICE_CHICKEN3 0xe184
-#define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8)
-#define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1)
-
#define G4X_AUD_VID_DID (dev_priv->info->display_mmio_offset + 0x62020)
#define INTEL_AUDIO_DEVCL 0x808629FB
#define INTEL_AUDIO_DEVBLC 0x80862801
@@ -5069,18 +4781,6 @@
CPT_AUD_CNTL_ST_B)
#define CPT_AUD_CNTRL_ST2 0xE50C0
-#define VLV_HDMIW_HDMIEDID_A (VLV_DISPLAY_BASE + 0x62050)
-#define VLV_HDMIW_HDMIEDID_B (VLV_DISPLAY_BASE + 0x62150)
-#define VLV_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \
- VLV_HDMIW_HDMIEDID_A, \
- VLV_HDMIW_HDMIEDID_B)
-#define VLV_AUD_CNTL_ST_A (VLV_DISPLAY_BASE + 0x620B4)
-#define VLV_AUD_CNTL_ST_B (VLV_DISPLAY_BASE + 0x621B4)
-#define VLV_AUD_CNTL_ST(pipe) _PIPE(pipe, \
- VLV_AUD_CNTL_ST_A, \
- VLV_AUD_CNTL_ST_B)
-#define VLV_AUD_CNTL_ST2 (VLV_DISPLAY_BASE + 0x620C0)
-
/* These are the 4 32-bit write offset registers for each stream
* output buffer. It determines the offset from the
* 3DSTATE_SO_BUFFERs that the next streamed vertex output goes to.
@@ -5097,12 +4797,6 @@
#define CPT_AUD_CFG(pipe) _PIPE(pipe, \
CPT_AUD_CONFIG_A, \
CPT_AUD_CONFIG_B)
-#define VLV_AUD_CONFIG_A (VLV_DISPLAY_BASE + 0x62000)
-#define VLV_AUD_CONFIG_B (VLV_DISPLAY_BASE + 0x62100)
-#define VLV_AUD_CFG(pipe) _PIPE(pipe, \
- VLV_AUD_CONFIG_A, \
- VLV_AUD_CONFIG_B)
-
#define AUD_CONFIG_N_VALUE_INDEX (1 << 29)
#define AUD_CONFIG_N_PROG_ENABLE (1 << 28)
#define AUD_CONFIG_UPPER_N_SHIFT 20
@@ -5110,17 +4804,7 @@
#define AUD_CONFIG_LOWER_N_SHIFT 4
#define AUD_CONFIG_LOWER_N_VALUE (0xfff << 4)
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK (0xf << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 (0 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 (1 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 (2 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 (3 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 (4 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 (5 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 (6 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 (7 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 (8 << 16)
-#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 (9 << 16)
+#define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16)
#define AUD_CONFIG_DISABLE_NCTS (1 << 3)
/* HSW Audio */
@@ -5245,7 +4929,6 @@
#define DDI_BUF_CTL_B 0x64100
#define DDI_BUF_CTL(port) _PORT(port, DDI_BUF_CTL_A, DDI_BUF_CTL_B)
#define DDI_BUF_CTL_ENABLE (1<<31)
-/* Haswell */
#define DDI_BUF_EMP_400MV_0DB_HSW (0<<24) /* Sel0 */
#define DDI_BUF_EMP_400MV_3_5DB_HSW (1<<24) /* Sel1 */
#define DDI_BUF_EMP_400MV_6DB_HSW (2<<24) /* Sel2 */
@@ -5255,16 +4938,6 @@
#define DDI_BUF_EMP_600MV_6DB_HSW (6<<24) /* Sel6 */
#define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */
#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */
-/* Broadwell */
-#define DDI_BUF_EMP_400MV_0DB_BDW (0<<24) /* Sel0 */
-#define DDI_BUF_EMP_400MV_3_5DB_BDW (1<<24) /* Sel1 */
-#define DDI_BUF_EMP_400MV_6DB_BDW (2<<24) /* Sel2 */
-#define DDI_BUF_EMP_600MV_0DB_BDW (3<<24) /* Sel3 */
-#define DDI_BUF_EMP_600MV_3_5DB_BDW (4<<24) /* Sel4 */
-#define DDI_BUF_EMP_600MV_6DB_BDW (5<<24) /* Sel5 */
-#define DDI_BUF_EMP_800MV_0DB_BDW (6<<24) /* Sel6 */
-#define DDI_BUF_EMP_800MV_3_5DB_BDW (7<<24) /* Sel7 */
-#define DDI_BUF_EMP_1200MV_0DB_BDW (8<<24) /* Sel8 */
#define DDI_BUF_EMP_MASK (0xf<<24)
#define DDI_BUF_PORT_REVERSAL (1<<16)
#define DDI_BUF_IS_IDLE (1<<7)
@@ -5374,9 +5047,6 @@
#define LCPLL_PLL_LOCK (1<<30)
#define LCPLL_CLK_FREQ_MASK (3<<26)
#define LCPLL_CLK_FREQ_450 (0<<26)
-#define LCPLL_CLK_FREQ_54O_BDW (1<<26)
-#define LCPLL_CLK_FREQ_337_5_BDW (2<<26)
-#define LCPLL_CLK_FREQ_675_BDW (3<<26)
#define LCPLL_CD_CLOCK_DISABLE (1<<25)
#define LCPLL_CD2X_CLOCK_DISABLE (1<<23)
#define LCPLL_POWER_DOWN_ALLOW (1<<22)
@@ -5458,414 +5128,4 @@
#define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
#define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
-/* VLV MIPI registers */
-
-#define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190)
-#define _MIPIB_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700)
-#define MIPI_PORT_CTRL(pipe) _PIPE(pipe, _MIPIA_PORT_CTRL, _MIPIB_PORT_CTRL)
-#define DPI_ENABLE (1 << 31) /* A + B */
-#define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27
-#define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27)
-#define DUAL_LINK_MODE_MASK (1 << 26)
-#define DUAL_LINK_MODE_FRONT_BACK (0 << 26)
-#define DUAL_LINK_MODE_PIXEL_ALTERNATIVE (1 << 26)
-#define DITHERING_ENABLE (1 << 25) /* A + B */
-#define FLOPPED_HSTX (1 << 23)
-#define DE_INVERT (1 << 19) /* XXX */
-#define MIPIA_FLISDSI_DELAY_COUNT_SHIFT 18
-#define MIPIA_FLISDSI_DELAY_COUNT_MASK (0xf << 18)
-#define AFE_LATCHOUT (1 << 17)
-#define LP_OUTPUT_HOLD (1 << 16)
-#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_SHIFT 15
-#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_MASK (1 << 15)
-#define MIPIB_MIPI4DPHY_DELAY_COUNT_SHIFT 11
-#define MIPIB_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 11)
-#define CSB_SHIFT 9
-#define CSB_MASK (3 << 9)
-#define CSB_20MHZ (0 << 9)
-#define CSB_10MHZ (1 << 9)
-#define CSB_40MHZ (2 << 9)
-#define BANDGAP_MASK (1 << 8)
-#define BANDGAP_PNW_CIRCUIT (0 << 8)
-#define BANDGAP_LNC_CIRCUIT (1 << 8)
-#define MIPIB_FLISDSI_DELAY_COUNT_LOW_SHIFT 5
-#define MIPIB_FLISDSI_DELAY_COUNT_LOW_MASK (7 << 5)
-#define TEARING_EFFECT_DELAY (1 << 4) /* A + B */
-#define TEARING_EFFECT_SHIFT 2 /* A + B */
-#define TEARING_EFFECT_MASK (3 << 2)
-#define TEARING_EFFECT_OFF (0 << 2)
-#define TEARING_EFFECT_DSI (1 << 2)
-#define TEARING_EFFECT_GPIO (2 << 2)
-#define LANE_CONFIGURATION_SHIFT 0
-#define LANE_CONFIGURATION_MASK (3 << 0)
-#define LANE_CONFIGURATION_4LANE (0 << 0)
-#define LANE_CONFIGURATION_DUAL_LINK_A (1 << 0)
-#define LANE_CONFIGURATION_DUAL_LINK_B (2 << 0)
-
-#define _MIPIA_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61194)
-#define _MIPIB_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61704)
-#define MIPI_TEARING_CTRL(pipe) _PIPE(pipe, _MIPIA_TEARING_CTRL, _MIPIB_TEARING_CTRL)
-#define TEARING_EFFECT_DELAY_SHIFT 0
-#define TEARING_EFFECT_DELAY_MASK (0xffff << 0)
-
-/* XXX: all bits reserved */
-#define _MIPIA_AUTOPWG (VLV_DISPLAY_BASE + 0x611a0)
-
-/* MIPI DSI Controller and D-PHY registers */
-
-#define _MIPIA_DEVICE_READY (VLV_DISPLAY_BASE + 0xb000)
-#define _MIPIB_DEVICE_READY (VLV_DISPLAY_BASE + 0xb800)
-#define MIPI_DEVICE_READY(pipe) _PIPE(pipe, _MIPIA_DEVICE_READY, _MIPIB_DEVICE_READY)
-#define BUS_POSSESSION (1 << 3) /* set to give bus to receiver */
-#define ULPS_STATE_MASK (3 << 1)
-#define ULPS_STATE_ENTER (2 << 1)
-#define ULPS_STATE_EXIT (1 << 1)
-#define ULPS_STATE_NORMAL_OPERATION (0 << 1)
-#define DEVICE_READY (1 << 0)
-
-#define _MIPIA_INTR_STAT (VLV_DISPLAY_BASE + 0xb004)
-#define _MIPIB_INTR_STAT (VLV_DISPLAY_BASE + 0xb804)
-#define MIPI_INTR_STAT(pipe) _PIPE(pipe, _MIPIA_INTR_STAT, _MIPIB_INTR_STAT)
-#define _MIPIA_INTR_EN (VLV_DISPLAY_BASE + 0xb008)
-#define _MIPIB_INTR_EN (VLV_DISPLAY_BASE + 0xb808)
-#define MIPI_INTR_EN(pipe) _PIPE(pipe, _MIPIA_INTR_EN, _MIPIB_INTR_EN)
-#define TEARING_EFFECT (1 << 31)
-#define SPL_PKT_SENT_INTERRUPT (1 << 30)
-#define GEN_READ_DATA_AVAIL (1 << 29)
-#define LP_GENERIC_WR_FIFO_FULL (1 << 28)
-#define HS_GENERIC_WR_FIFO_FULL (1 << 27)
-#define RX_PROT_VIOLATION (1 << 26)
-#define RX_INVALID_TX_LENGTH (1 << 25)
-#define ACK_WITH_NO_ERROR (1 << 24)
-#define TURN_AROUND_ACK_TIMEOUT (1 << 23)
-#define LP_RX_TIMEOUT (1 << 22)
-#define HS_TX_TIMEOUT (1 << 21)
-#define DPI_FIFO_UNDERRUN (1 << 20)
-#define LOW_CONTENTION (1 << 19)
-#define HIGH_CONTENTION (1 << 18)
-#define TXDSI_VC_ID_INVALID (1 << 17)
-#define TXDSI_DATA_TYPE_NOT_RECOGNISED (1 << 16)
-#define TXCHECKSUM_ERROR (1 << 15)
-#define TXECC_MULTIBIT_ERROR (1 << 14)
-#define TXECC_SINGLE_BIT_ERROR (1 << 13)
-#define TXFALSE_CONTROL_ERROR (1 << 12)
-#define RXDSI_VC_ID_INVALID (1 << 11)
-#define RXDSI_DATA_TYPE_NOT_REGOGNISED (1 << 10)
-#define RXCHECKSUM_ERROR (1 << 9)
-#define RXECC_MULTIBIT_ERROR (1 << 8)
-#define RXECC_SINGLE_BIT_ERROR (1 << 7)
-#define RXFALSE_CONTROL_ERROR (1 << 6)
-#define RXHS_RECEIVE_TIMEOUT_ERROR (1 << 5)
-#define RX_LP_TX_SYNC_ERROR (1 << 4)
-#define RXEXCAPE_MODE_ENTRY_ERROR (1 << 3)
-#define RXEOT_SYNC_ERROR (1 << 2)
-#define RXSOT_SYNC_ERROR (1 << 1)
-#define RXSOT_ERROR (1 << 0)
-
-#define _MIPIA_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb00c)
-#define _MIPIB_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb80c)
-#define MIPI_DSI_FUNC_PRG(pipe) _PIPE(pipe, _MIPIA_DSI_FUNC_PRG, _MIPIB_DSI_FUNC_PRG)
-#define CMD_MODE_DATA_WIDTH_MASK (7 << 13)
-#define CMD_MODE_NOT_SUPPORTED (0 << 13)
-#define CMD_MODE_DATA_WIDTH_16_BIT (1 << 13)
-#define CMD_MODE_DATA_WIDTH_9_BIT (2 << 13)
-#define CMD_MODE_DATA_WIDTH_8_BIT (3 << 13)
-#define CMD_MODE_DATA_WIDTH_OPTION1 (4 << 13)
-#define CMD_MODE_DATA_WIDTH_OPTION2 (5 << 13)
-#define VID_MODE_FORMAT_MASK (0xf << 7)
-#define VID_MODE_NOT_SUPPORTED (0 << 7)
-#define VID_MODE_FORMAT_RGB565 (1 << 7)
-#define VID_MODE_FORMAT_RGB666 (2 << 7)
-#define VID_MODE_FORMAT_RGB666_LOOSE (3 << 7)
-#define VID_MODE_FORMAT_RGB888 (4 << 7)
-#define CMD_MODE_CHANNEL_NUMBER_SHIFT 5
-#define CMD_MODE_CHANNEL_NUMBER_MASK (3 << 5)
-#define VID_MODE_CHANNEL_NUMBER_SHIFT 3
-#define VID_MODE_CHANNEL_NUMBER_MASK (3 << 3)
-#define DATA_LANES_PRG_REG_SHIFT 0
-#define DATA_LANES_PRG_REG_MASK (7 << 0)
-
-#define _MIPIA_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb010)
-#define _MIPIB_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb810)
-#define MIPI_HS_TX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_HS_TX_TIMEOUT, _MIPIB_HS_TX_TIMEOUT)
-#define HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK 0xffffff
-
-#define _MIPIA_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb014)
-#define _MIPIB_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb814)
-#define MIPI_LP_RX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_LP_RX_TIMEOUT, _MIPIB_LP_RX_TIMEOUT)
-#define LOW_POWER_RX_TIMEOUT_COUNTER_MASK 0xffffff
-
-#define _MIPIA_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb018)
-#define _MIPIB_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb818)
-#define MIPI_TURN_AROUND_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIB_TURN_AROUND_TIMEOUT)
-#define TURN_AROUND_TIMEOUT_MASK 0x3f
-
-#define _MIPIA_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb01c)
-#define _MIPIB_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb81c)
-#define MIPI_DEVICE_RESET_TIMER(pipe) _PIPE(pipe, _MIPIA_DEVICE_RESET_TIMER, _MIPIB_DEVICE_RESET_TIMER)
-#define DEVICE_RESET_TIMER_MASK 0xffff
-
-#define _MIPIA_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb020)
-#define _MIPIB_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb820)
-#define MIPI_DPI_RESOLUTION(pipe) _PIPE(pipe, _MIPIA_DPI_RESOLUTION, _MIPIB_DPI_RESOLUTION)
-#define VERTICAL_ADDRESS_SHIFT 16
-#define VERTICAL_ADDRESS_MASK (0xffff << 16)
-#define HORIZONTAL_ADDRESS_SHIFT 0
-#define HORIZONTAL_ADDRESS_MASK 0xffff
-
-#define _MIPIA_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb024)
-#define _MIPIB_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb824)
-#define MIPI_DBI_FIFO_THROTTLE(pipe) _PIPE(pipe, _MIPIA_DBI_FIFO_THROTTLE, _MIPIB_DBI_FIFO_THROTTLE)
-#define DBI_FIFO_EMPTY_HALF (0 << 0)
-#define DBI_FIFO_EMPTY_QUARTER (1 << 0)
-#define DBI_FIFO_EMPTY_7_LOCATIONS (2 << 0)
-
-/* regs below are bits 15:0 */
-#define _MIPIA_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb028)
-#define _MIPIB_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb828)
-#define MIPI_HSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_HSYNC_PADDING_COUNT, _MIPIB_HSYNC_PADDING_COUNT)
-
-#define _MIPIA_HBP_COUNT (VLV_DISPLAY_BASE + 0xb02c)
-#define _MIPIB_HBP_COUNT (VLV_DISPLAY_BASE + 0xb82c)
-#define MIPI_HBP_COUNT(pipe) _PIPE(pipe, _MIPIA_HBP_COUNT, _MIPIB_HBP_COUNT)
-
-#define _MIPIA_HFP_COUNT (VLV_DISPLAY_BASE + 0xb030)
-#define _MIPIB_HFP_COUNT (VLV_DISPLAY_BASE + 0xb830)
-#define MIPI_HFP_COUNT(pipe) _PIPE(pipe, _MIPIA_HFP_COUNT, _MIPIB_HFP_COUNT)
-
-#define _MIPIA_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb034)
-#define _MIPIB_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb834)
-#define MIPI_HACTIVE_AREA_COUNT(pipe) _PIPE(pipe, _MIPIA_HACTIVE_AREA_COUNT, _MIPIB_HACTIVE_AREA_COUNT)
-
-#define _MIPIA_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb038)
-#define _MIPIB_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb838)
-#define MIPI_VSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_VSYNC_PADDING_COUNT, _MIPIB_VSYNC_PADDING_COUNT)
-
-#define _MIPIA_VBP_COUNT (VLV_DISPLAY_BASE + 0xb03c)
-#define _MIPIB_VBP_COUNT (VLV_DISPLAY_BASE + 0xb83c)
-#define MIPI_VBP_COUNT(pipe) _PIPE(pipe, _MIPIA_VBP_COUNT, _MIPIB_VBP_COUNT)
-
-#define _MIPIA_VFP_COUNT (VLV_DISPLAY_BASE + 0xb040)
-#define _MIPIB_VFP_COUNT (VLV_DISPLAY_BASE + 0xb840)
-#define MIPI_VFP_COUNT(pipe) _PIPE(pipe, _MIPIA_VFP_COUNT, _MIPIB_VFP_COUNT)
-
-#define _MIPIA_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb044)
-#define _MIPIB_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb844)
-#define MIPI_HIGH_LOW_SWITCH_COUNT(pipe) _PIPE(pipe, _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIB_HIGH_LOW_SWITCH_COUNT)
-/* regs above are bits 15:0 */
-
-#define _MIPIA_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb048)
-#define _MIPIB_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb848)
-#define MIPI_DPI_CONTROL(pipe) _PIPE(pipe, _MIPIA_DPI_CONTROL, _MIPIB_DPI_CONTROL)
-#define DPI_LP_MODE (1 << 6)
-#define BACKLIGHT_OFF (1 << 5)
-#define BACKLIGHT_ON (1 << 4)
-#define COLOR_MODE_OFF (1 << 3)
-#define COLOR_MODE_ON (1 << 2)
-#define TURN_ON (1 << 1)
-#define SHUTDOWN (1 << 0)
-
-#define _MIPIA_DPI_DATA (VLV_DISPLAY_BASE + 0xb04c)
-#define _MIPIB_DPI_DATA (VLV_DISPLAY_BASE + 0xb84c)
-#define MIPI_DPI_DATA(pipe) _PIPE(pipe, _MIPIA_DPI_DATA, _MIPIB_DPI_DATA)
-#define COMMAND_BYTE_SHIFT 0
-#define COMMAND_BYTE_MASK (0x3f << 0)
-
-#define _MIPIA_INIT_COUNT (VLV_DISPLAY_BASE + 0xb050)
-#define _MIPIB_INIT_COUNT (VLV_DISPLAY_BASE + 0xb850)
-#define MIPI_INIT_COUNT(pipe) _PIPE(pipe, _MIPIA_INIT_COUNT, _MIPIB_INIT_COUNT)
-#define MASTER_INIT_TIMER_SHIFT 0
-#define MASTER_INIT_TIMER_MASK (0xffff << 0)
-
-#define _MIPIA_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb054)
-#define _MIPIB_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb854)
-#define MIPI_MAX_RETURN_PKT_SIZE(pipe) _PIPE(pipe, _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIB_MAX_RETURN_PKT_SIZE)
-#define MAX_RETURN_PKT_SIZE_SHIFT 0
-#define MAX_RETURN_PKT_SIZE_MASK (0x3ff << 0)
-
-#define _MIPIA_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb058)
-#define _MIPIB_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb858)
-#define MIPI_VIDEO_MODE_FORMAT(pipe) _PIPE(pipe, _MIPIA_VIDEO_MODE_FORMAT, _MIPIB_VIDEO_MODE_FORMAT)
-#define RANDOM_DPI_DISPLAY_RESOLUTION (1 << 4)
-#define DISABLE_VIDEO_BTA (1 << 3)
-#define IP_TG_CONFIG (1 << 2)
-#define VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE (1 << 0)
-#define VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS (2 << 0)
-#define VIDEO_MODE_BURST (3 << 0)
-
-#define _MIPIA_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb05c)
-#define _MIPIB_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb85c)
-#define MIPI_EOT_DISABLE(pipe) _PIPE(pipe, _MIPIA_EOT_DISABLE, _MIPIB_EOT_DISABLE)
-#define LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 7)
-#define HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 6)
-#define LOW_CONTENTION_RECOVERY_DISABLE (1 << 5)
-#define HIGH_CONTENTION_RECOVERY_DISABLE (1 << 4)
-#define TXDSI_TYPE_NOT_RECOGNISED_ERROR_RECOVERY_DISABLE (1 << 3)
-#define TXECC_MULTIBIT_ERROR_RECOVERY_DISABLE (1 << 2)
-#define CLOCKSTOP (1 << 1)
-#define EOT_DISABLE (1 << 0)
-
-#define _MIPIA_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb060)
-#define _MIPIB_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb860)
-#define MIPI_LP_BYTECLK(pipe) _PIPE(pipe, _MIPIA_LP_BYTECLK, _MIPIB_LP_BYTECLK)
-#define LP_BYTECLK_SHIFT 0
-#define LP_BYTECLK_MASK (0xffff << 0)
-
-/* bits 31:0 */
-#define _MIPIA_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb064)
-#define _MIPIB_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb864)
-#define MIPI_LP_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_LP_GEN_DATA, _MIPIB_LP_GEN_DATA)
-
-/* bits 31:0 */
-#define _MIPIA_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb068)
-#define _MIPIB_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb868)
-#define MIPI_HS_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_HS_GEN_DATA, _MIPIB_HS_GEN_DATA)
-
-#define _MIPIA_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb06c)
-#define _MIPIB_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb86c)
-#define MIPI_LP_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_LP_GEN_CTRL, _MIPIB_LP_GEN_CTRL)
-#define _MIPIA_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb070)
-#define _MIPIB_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb870)
-#define MIPI_HS_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_HS_GEN_CTRL, _MIPIB_HS_GEN_CTRL)
-#define LONG_PACKET_WORD_COUNT_SHIFT 8
-#define LONG_PACKET_WORD_COUNT_MASK (0xffff << 8)
-#define SHORT_PACKET_PARAM_SHIFT 8
-#define SHORT_PACKET_PARAM_MASK (0xffff << 8)
-#define VIRTUAL_CHANNEL_SHIFT 6
-#define VIRTUAL_CHANNEL_MASK (3 << 6)
-#define DATA_TYPE_SHIFT 0
-#define DATA_TYPE_MASK (3f << 0)
-/* data type values, see include/video/mipi_display.h */
-
-#define _MIPIA_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb074)
-#define _MIPIB_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb874)
-#define MIPI_GEN_FIFO_STAT(pipe) _PIPE(pipe, _MIPIA_GEN_FIFO_STAT, _MIPIB_GEN_FIFO_STAT)
-#define DPI_FIFO_EMPTY (1 << 28)
-#define DBI_FIFO_EMPTY (1 << 27)
-#define LP_CTRL_FIFO_EMPTY (1 << 26)
-#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25)
-#define LP_CTRL_FIFO_FULL (1 << 24)
-#define HS_CTRL_FIFO_EMPTY (1 << 18)
-#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17)
-#define HS_CTRL_FIFO_FULL (1 << 16)
-#define LP_DATA_FIFO_EMPTY (1 << 10)
-#define LP_DATA_FIFO_HALF_EMPTY (1 << 9)
-#define LP_DATA_FIFO_FULL (1 << 8)
-#define HS_DATA_FIFO_EMPTY (1 << 2)
-#define HS_DATA_FIFO_HALF_EMPTY (1 << 1)
-#define HS_DATA_FIFO_FULL (1 << 0)
-
-#define _MIPIA_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb078)
-#define _MIPIB_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb878)
-#define MIPI_HS_LP_DBI_ENABLE(pipe) _PIPE(pipe, _MIPIA_HS_LS_DBI_ENABLE, _MIPIB_HS_LS_DBI_ENABLE)
-#define DBI_HS_LP_MODE_MASK (1 << 0)
-#define DBI_LP_MODE (1 << 0)
-#define DBI_HS_MODE (0 << 0)
-
-#define _MIPIA_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb080)
-#define _MIPIB_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb880)
-#define MIPI_DPHY_PARAM(pipe) _PIPE(pipe, _MIPIA_DPHY_PARAM, _MIPIB_DPHY_PARAM)
-#define EXIT_ZERO_COUNT_SHIFT 24
-#define EXIT_ZERO_COUNT_MASK (0x3f << 24)
-#define TRAIL_COUNT_SHIFT 16
-#define TRAIL_COUNT_MASK (0x1f << 16)
-#define CLK_ZERO_COUNT_SHIFT 8
-#define CLK_ZERO_COUNT_MASK (0xff << 8)
-#define PREPARE_COUNT_SHIFT 0
-#define PREPARE_COUNT_MASK (0x3f << 0)
-
-/* bits 31:0 */
-#define _MIPIA_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb084)
-#define _MIPIB_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb884)
-#define MIPI_DBI_BW_CTRL(pipe) _PIPE(pipe, _MIPIA_DBI_BW_CTRL, _MIPIB_DBI_BW_CTRL)
-
-#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb088)
-#define _MIPIB_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb888)
-#define MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe) _PIPE(pipe, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIB_CLK_LANE_SWITCH_TIME_CNT)
-#define LP_HS_SSW_CNT_SHIFT 16
-#define LP_HS_SSW_CNT_MASK (0xffff << 16)
-#define HS_LP_PWR_SW_CNT_SHIFT 0
-#define HS_LP_PWR_SW_CNT_MASK (0xffff << 0)
-
-#define _MIPIA_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb08c)
-#define _MIPIB_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb88c)
-#define MIPI_STOP_STATE_STALL(pipe) _PIPE(pipe, _MIPIA_STOP_STATE_STALL, _MIPIB_STOP_STATE_STALL)
-#define STOP_STATE_STALL_COUNTER_SHIFT 0
-#define STOP_STATE_STALL_COUNTER_MASK (0xff << 0)
-
-#define _MIPIA_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb090)
-#define _MIPIB_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb890)
-#define MIPI_INTR_STAT_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_STAT_REG_1, _MIPIB_INTR_STAT_REG_1)
-#define _MIPIA_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb094)
-#define _MIPIB_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb894)
-#define MIPI_INTR_EN_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_EN_REG_1, _MIPIB_INTR_EN_REG_1)
-#define RX_CONTENTION_DETECTED (1 << 0)
-
-/* XXX: only pipe A ?!? */
-#define MIPIA_DBI_TYPEC_CTRL (VLV_DISPLAY_BASE + 0xb100)
-#define DBI_TYPEC_ENABLE (1 << 31)
-#define DBI_TYPEC_WIP (1 << 30)
-#define DBI_TYPEC_OPTION_SHIFT 28
-#define DBI_TYPEC_OPTION_MASK (3 << 28)
-#define DBI_TYPEC_FREQ_SHIFT 24
-#define DBI_TYPEC_FREQ_MASK (0xf << 24)
-#define DBI_TYPEC_OVERRIDE (1 << 8)
-#define DBI_TYPEC_OVERRIDE_COUNTER_SHIFT 0
-#define DBI_TYPEC_OVERRIDE_COUNTER_MASK (0xff << 0)
-
-
-/* MIPI adapter registers */
-
-#define _MIPIA_CTRL (VLV_DISPLAY_BASE + 0xb104)
-#define _MIPIB_CTRL (VLV_DISPLAY_BASE + 0xb904)
-#define MIPI_CTRL(pipe) _PIPE(pipe, _MIPIA_CTRL, _MIPIB_CTRL)
-#define ESCAPE_CLOCK_DIVIDER_SHIFT 5 /* A only */
-#define ESCAPE_CLOCK_DIVIDER_MASK (3 << 5)
-#define ESCAPE_CLOCK_DIVIDER_1 (0 << 5)
-#define ESCAPE_CLOCK_DIVIDER_2 (1 << 5)
-#define ESCAPE_CLOCK_DIVIDER_4 (2 << 5)
-#define READ_REQUEST_PRIORITY_SHIFT 3
-#define READ_REQUEST_PRIORITY_MASK (3 << 3)
-#define READ_REQUEST_PRIORITY_LOW (0 << 3)
-#define READ_REQUEST_PRIORITY_HIGH (3 << 3)
-#define RGB_FLIP_TO_BGR (1 << 2)
-
-#define _MIPIA_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb108)
-#define _MIPIB_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb908)
-#define MIPI_DATA_ADDRESS(pipe) _PIPE(pipe, _MIPIA_DATA_ADDRESS, _MIPIB_DATA_ADDRESS)
-#define DATA_MEM_ADDRESS_SHIFT 5
-#define DATA_MEM_ADDRESS_MASK (0x7ffffff << 5)
-#define DATA_VALID (1 << 0)
-
-#define _MIPIA_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb10c)
-#define _MIPIB_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb90c)
-#define MIPI_DATA_LENGTH(pipe) _PIPE(pipe, _MIPIA_DATA_LENGTH, _MIPIB_DATA_LENGTH)
-#define DATA_LENGTH_SHIFT 0
-#define DATA_LENGTH_MASK (0xfffff << 0)
-
-#define _MIPIA_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb110)
-#define _MIPIB_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb910)
-#define MIPI_COMMAND_ADDRESS(pipe) _PIPE(pipe, _MIPIA_COMMAND_ADDRESS, _MIPIB_COMMAND_ADDRESS)
-#define COMMAND_MEM_ADDRESS_SHIFT 5
-#define COMMAND_MEM_ADDRESS_MASK (0x7ffffff << 5)
-#define AUTO_PWG_ENABLE (1 << 2)
-#define MEMORY_WRITE_DATA_FROM_PIPE_RENDERING (1 << 1)
-#define COMMAND_VALID (1 << 0)
-
-#define _MIPIA_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb114)
-#define _MIPIB_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb914)
-#define MIPI_COMMAND_LENGTH(pipe) _PIPE(pipe, _MIPIA_COMMAND_LENGTH, _MIPIB_COMMAND_LENGTH)
-#define COMMAND_LENGTH_SHIFT(n) (8 * (n)) /* n: 0...3 */
-#define COMMAND_LENGTH_MASK(n) (0xff << (8 * (n)))
-
-#define _MIPIA_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb118)
-#define _MIPIB_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb918)
-#define MIPI_READ_DATA_RETURN(pipe, n) \
- (_PIPE(pipe, _MIPIA_READ_DATA_RETURN0, _MIPIB_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */
-
-#define _MIPIA_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb138)
-#define _MIPIB_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb938)
-#define MIPI_READ_DATA_VALID(pipe) _PIPE(pipe, _MIPIA_READ_DATA_VALID, _MIPIB_READ_DATA_VALID)
-#define READ_DATA_VALID(n) (1 << (n))
-
#endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 98790c7..70db618 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -214,22 +214,6 @@ static void i915_save_display(struct drm_device *dev)
dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
- } else if (IS_VALLEYVIEW(dev)) {
- dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
- dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
-
- dev_priv->regfile.saveBLC_PWM_CTL =
- I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
- dev_priv->regfile.saveBLC_HIST_CTL =
- I915_READ(VLV_BLC_HIST_CTL(PIPE_A));
- dev_priv->regfile.saveBLC_PWM_CTL2 =
- I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
- dev_priv->regfile.saveBLC_PWM_CTL_B =
- I915_READ(VLV_BLC_PWM_CTL(PIPE_B));
- dev_priv->regfile.saveBLC_HIST_CTL_B =
- I915_READ(VLV_BLC_HIST_CTL(PIPE_B));
- dev_priv->regfile.saveBLC_PWM_CTL2_B =
- I915_READ(VLV_BLC_PWM_CTL2(PIPE_B));
} else {
dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
@@ -318,19 +302,6 @@ static void i915_restore_display(struct drm_device *dev)
I915_WRITE(PCH_PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
I915_WRITE(RSTDBYCTL,
dev_priv->regfile.saveMCHBAR_RENDER_STANDBY);
- } else if (IS_VALLEYVIEW(dev)) {
- I915_WRITE(VLV_BLC_PWM_CTL(PIPE_A),
- dev_priv->regfile.saveBLC_PWM_CTL);
- I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A),
- dev_priv->regfile.saveBLC_HIST_CTL);
- I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_A),
- dev_priv->regfile.saveBLC_PWM_CTL2);
- I915_WRITE(VLV_BLC_PWM_CTL(PIPE_B),
- dev_priv->regfile.saveBLC_PWM_CTL);
- I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B),
- dev_priv->regfile.saveBLC_HIST_CTL);
- I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_B),
- dev_priv->regfile.saveBLC_PWM_CTL2);
} else {
I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS);
I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
@@ -369,9 +340,7 @@ int i915_save_state(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
- if (INTEL_INFO(dev)->gen <= 4)
- pci_read_config_byte(dev->pdev, LBB,
- &dev_priv->regfile.saveLBB);
+ pci_read_config_byte(dev->pdev, LBB, &dev_priv->regfile.saveLBB);
mutex_lock(&dev->struct_mutex);
@@ -398,8 +367,7 @@ int i915_save_state(struct drm_device *dev)
intel_disable_gt_powersave(dev);
/* Cache mode state */
- if (INTEL_INFO(dev)->gen < 7)
- dev_priv->regfile.saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
+ dev_priv->regfile.saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
/* Memory Arbitration state */
dev_priv->regfile.saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
@@ -422,9 +390,7 @@ int i915_restore_state(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
- if (INTEL_INFO(dev)->gen <= 4)
- pci_write_config_byte(dev->pdev, LBB,
- dev_priv->regfile.saveLBB);
+ pci_write_config_byte(dev->pdev, LBB, dev_priv->regfile.saveLBB);
mutex_lock(&dev->struct_mutex);
@@ -448,9 +414,7 @@ int i915_restore_state(struct drm_device *dev)
}
/* Cache mode state */
- if (INTEL_INFO(dev)->gen < 7)
- I915_WRITE(CACHE_MODE_0, dev_priv->regfile.saveCACHE_MODE_0 |
- 0xffff0000);
+ I915_WRITE(CACHE_MODE_0, dev_priv->regfile.saveCACHE_MODE_0 | 0xffff0000);
/* Memory arbitration state */
I915_WRITE(MI_ARB_STATE, dev_priv->regfile.saveMI_ARB_STATE | 0xffff0000);
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index cef38fd..c8c4112 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -32,50 +32,30 @@
#include "intel_drv.h"
#include "i915_drv.h"
-#define dev_to_drm_minor(d) dev_get_drvdata((d))
-
#ifdef CONFIG_PM
static u32 calc_residency(struct drm_device *dev, const u32 reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u64 raw_time; /* 32b value may overflow during fixed point math */
- u64 units = 128ULL, div = 100000ULL, bias = 100ULL;
if (!intel_enable_rc6(dev))
return 0;
- /* On VLV, residency time is in CZ units rather than 1.28us */
- if (IS_VALLEYVIEW(dev)) {
- u32 clkctl2;
-
- clkctl2 = I915_READ(VLV_CLK_CTL2) >>
- CLK_CTL2_CZCOUNT_30NS_SHIFT;
- if (!clkctl2) {
- WARN(!clkctl2, "bogus CZ count value");
- return 0;
- }
- units = DIV_ROUND_UP_ULL(30ULL * bias, (u64)clkctl2);
- if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
- units <<= 8;
-
- div = 1000000ULL * bias;
- }
-
- raw_time = I915_READ(reg) * units;
- return DIV_ROUND_UP_ULL(raw_time, div);
+ raw_time = I915_READ(reg) * 128ULL;
+ return DIV_ROUND_UP_ULL(raw_time, 100000);
}
static ssize_t
show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = dev_to_drm_minor(kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6(dminor->dev));
}
static ssize_t
show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = dev_get_drvdata(kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6);
return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency);
}
@@ -83,20 +63,16 @@ show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
static ssize_t
show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = dev_to_drm_minor(kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p);
- if (IS_VALLEYVIEW(dminor->dev))
- rc6p_residency = 0;
return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency);
}
static ssize_t
show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = dev_to_drm_minor(kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp);
- if (IS_VALLEYVIEW(dminor->dev))
- rc6pp_residency = 0;
return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency);
}
@@ -121,7 +97,7 @@ static struct attribute_group rc6_attr_group = {
static int l3_access_valid(struct drm_device *dev, loff_t offset)
{
- if (!HAS_L3_DPF(dev))
+ if (!HAS_L3_GPU_CACHE(dev))
return -EPERM;
if (offset % 4 != 0)
@@ -139,34 +115,31 @@ i915_l3_read(struct file *filp, struct kobject *kobj,
loff_t offset, size_t count)
{
struct device *dev = container_of(kobj, struct device, kobj);
- struct drm_minor *dminor = dev_to_drm_minor(dev);
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
struct drm_device *drm_dev = dminor->dev;
struct drm_i915_private *dev_priv = drm_dev->dev_private;
- int slice = (int)(uintptr_t)attr->private;
- int ret;
-
- count = round_down(count, 4);
+ uint32_t misccpctl;
+ int i, ret;
ret = l3_access_valid(drm_dev, offset);
if (ret)
return ret;
- count = min_t(size_t, GEN7_L3LOG_SIZE - offset, count);
-
ret = i915_mutex_lock_interruptible(drm_dev);
if (ret)
return ret;
- if (dev_priv->l3_parity.remap_info[slice])
- memcpy(buf,
- dev_priv->l3_parity.remap_info[slice] + (offset/4),
- count);
- else
- memset(buf, 0, count);
+ misccpctl = I915_READ(GEN7_MISCCPCTL);
+ I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+
+ for (i = offset; count >= 4 && i < GEN7_L3LOG_SIZE; i += 4, count -= 4)
+ *((uint32_t *)(&buf[i])) = I915_READ(GEN7_L3LOG_BASE + i);
+
+ I915_WRITE(GEN7_MISCCPCTL, misccpctl);
mutex_unlock(&drm_dev->struct_mutex);
- return count;
+ return i - offset;
}
static ssize_t
@@ -175,26 +148,21 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
loff_t offset, size_t count)
{
struct device *dev = container_of(kobj, struct device, kobj);
- struct drm_minor *dminor = dev_to_drm_minor(dev);
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
struct drm_device *drm_dev = dminor->dev;
struct drm_i915_private *dev_priv = drm_dev->dev_private;
- struct i915_hw_context *ctx;
u32 *temp = NULL; /* Just here to make handling failures easy */
- int slice = (int)(uintptr_t)attr->private;
int ret;
ret = l3_access_valid(drm_dev, offset);
if (ret)
return ret;
- if (dev_priv->hw_contexts_disabled)
- return -ENXIO;
-
ret = i915_mutex_lock_interruptible(drm_dev);
if (ret)
return ret;
- if (!dev_priv->l3_parity.remap_info[slice]) {
+ if (!dev_priv->l3_parity.remap_info) {
temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL);
if (!temp) {
mutex_unlock(&drm_dev->struct_mutex);
@@ -214,13 +182,13 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
* at this point it is left as a TODO.
*/
if (temp)
- dev_priv->l3_parity.remap_info[slice] = temp;
+ dev_priv->l3_parity.remap_info = temp;
- memcpy(dev_priv->l3_parity.remap_info[slice] + (offset/4), buf, count);
+ memcpy(dev_priv->l3_parity.remap_info + (offset/4),
+ buf + (offset/4),
+ count);
- /* NB: We defer the remapping until we switch to the context */
- list_for_each_entry(ctx, &dev_priv->context_list, link)
- ctx->remap_slice |= (1<<slice);
+ i915_gem_l3_remap(drm_dev);
mutex_unlock(&drm_dev->struct_mutex);
@@ -232,29 +200,17 @@ static struct bin_attribute dpf_attrs = {
.size = GEN7_L3LOG_SIZE,
.read = i915_l3_read,
.write = i915_l3_write,
- .mmap = NULL,
- .private = (void *)0
-};
-
-static struct bin_attribute dpf_attrs_1 = {
- .attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)},
- .size = GEN7_L3LOG_SIZE,
- .read = i915_l3_read,
- .write = i915_l3_write,
- .mmap = NULL,
- .private = (void *)1
+ .mmap = NULL
};
static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
struct device_attribute *attr, char *buf)
{
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev_priv->dev)) {
u32 freq;
@@ -271,7 +227,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
struct device_attribute *attr, char *buf)
{
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -282,13 +238,11 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev_priv->dev))
ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.max_delay);
@@ -303,7 +257,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, rp_state_cap, hw_max, hw_min, non_oc_max;
@@ -313,8 +267,6 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
if (ret)
return ret;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev_priv->dev)) {
@@ -358,13 +310,11 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev_priv->dev))
ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.min_delay);
@@ -379,7 +329,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, rp_state_cap, hw_max, hw_min;
@@ -389,8 +339,6 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
if (ret)
return ret;
- flush_delayed_work(&dev_priv->rps.delayed_resume_work);
-
mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev)) {
@@ -440,7 +388,7 @@ static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
/* For now we have a static number of RP states */
static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, rp_state_cap;
@@ -488,7 +436,7 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
{
struct device *kdev = container_of(kobj, struct device, kobj);
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
struct i915_error_state_file_priv error_priv;
struct drm_i915_error_state_buf error_str;
@@ -523,7 +471,7 @@ static ssize_t error_state_write(struct file *file, struct kobject *kobj,
loff_t off, size_t count)
{
struct device *kdev = container_of(kobj, struct device, kobj);
- struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
struct drm_device *dev = minor->dev;
int ret;
@@ -553,34 +501,27 @@ void i915_setup_sysfs(struct drm_device *dev)
#ifdef CONFIG_PM
if (INTEL_INFO(dev)->gen >= 6) {
- ret = sysfs_merge_group(&dev->primary->kdev->kobj,
+ ret = sysfs_merge_group(&dev->primary->kdev.kobj,
&rc6_attr_group);
if (ret)
DRM_ERROR("RC6 residency sysfs setup failed\n");
}
#endif
- if (HAS_L3_DPF(dev)) {
- ret = device_create_bin_file(dev->primary->kdev, &dpf_attrs);
+ if (HAS_L3_GPU_CACHE(dev)) {
+ ret = device_create_bin_file(&dev->primary->kdev, &dpf_attrs);
if (ret)
DRM_ERROR("l3 parity sysfs setup failed\n");
-
- if (NUM_L3_SLICES(dev) > 1) {
- ret = device_create_bin_file(dev->primary->kdev,
- &dpf_attrs_1);
- if (ret)
- DRM_ERROR("l3 parity slice 1 setup failed\n");
- }
}
ret = 0;
if (IS_VALLEYVIEW(dev))
- ret = sysfs_create_files(&dev->primary->kdev->kobj, vlv_attrs);
+ ret = sysfs_create_files(&dev->primary->kdev.kobj, vlv_attrs);
else if (INTEL_INFO(dev)->gen >= 6)
- ret = sysfs_create_files(&dev->primary->kdev->kobj, gen6_attrs);
+ ret = sysfs_create_files(&dev->primary->kdev.kobj, gen6_attrs);
if (ret)
DRM_ERROR("RPS sysfs setup failed\n");
- ret = sysfs_create_bin_file(&dev->primary->kdev->kobj,
+ ret = sysfs_create_bin_file(&dev->primary->kdev.kobj,
&error_state_attr);
if (ret)
DRM_ERROR("error_state sysfs setup failed\n");
@@ -588,14 +529,13 @@ void i915_setup_sysfs(struct drm_device *dev)
void i915_teardown_sysfs(struct drm_device *dev)
{
- sysfs_remove_bin_file(&dev->primary->kdev->kobj, &error_state_attr);
+ sysfs_remove_bin_file(&dev->primary->kdev.kobj, &error_state_attr);
if (IS_VALLEYVIEW(dev))
- sysfs_remove_files(&dev->primary->kdev->kobj, vlv_attrs);
+ sysfs_remove_files(&dev->primary->kdev.kobj, vlv_attrs);
else
- sysfs_remove_files(&dev->primary->kdev->kobj, gen6_attrs);
- device_remove_bin_file(dev->primary->kdev, &dpf_attrs_1);
- device_remove_bin_file(dev->primary->kdev, &dpf_attrs);
+ sysfs_remove_files(&dev->primary->kdev.kobj, gen6_attrs);
+ device_remove_bin_file(&dev->primary->kdev, &dpf_attrs);
#ifdef CONFIG_PM
- sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group);
+ sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
#endif
}
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 6e580c9..e2c5ee6 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -233,47 +233,6 @@ TRACE_EVENT(i915_gem_evict_everything,
TP_printk("dev=%d", __entry->dev)
);
-TRACE_EVENT(i915_gem_evict_vm,
- TP_PROTO(struct i915_address_space *vm),
- TP_ARGS(vm),
-
- TP_STRUCT__entry(
- __field(struct i915_address_space *, vm)
- ),
-
- TP_fast_assign(
- __entry->vm = vm;
- ),
-
- TP_printk("dev=%d, vm=%p", __entry->vm->dev->primary->index, __entry->vm)
-);
-
-TRACE_EVENT(i915_gem_ring_sync_to,
- TP_PROTO(struct intel_ring_buffer *from,
- struct intel_ring_buffer *to,
- u32 seqno),
- TP_ARGS(from, to, seqno),
-
- TP_STRUCT__entry(
- __field(u32, dev)
- __field(u32, sync_from)
- __field(u32, sync_to)
- __field(u32, seqno)
- ),
-
- TP_fast_assign(
- __entry->dev = from->dev->primary->index;
- __entry->sync_from = from->id;
- __entry->sync_to = to->id;
- __entry->seqno = seqno;
- ),
-
- TP_printk("dev=%u, sync-from=%u, sync-to=%u, seqno=%u",
- __entry->dev,
- __entry->sync_from, __entry->sync_to,
- __entry->seqno)
-);
-
TRACE_EVENT(i915_gem_ring_dispatch,
TP_PROTO(struct intel_ring_buffer *ring, u32 seqno, u32 flags),
TP_ARGS(ring, seqno, flags),
@@ -345,24 +304,9 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
TP_ARGS(ring, seqno)
);
-TRACE_EVENT(i915_gem_request_complete,
- TP_PROTO(struct intel_ring_buffer *ring),
- TP_ARGS(ring),
-
- TP_STRUCT__entry(
- __field(u32, dev)
- __field(u32, ring)
- __field(u32, seqno)
- ),
-
- TP_fast_assign(
- __entry->dev = ring->dev->primary->index;
- __entry->ring = ring->id;
- __entry->seqno = ring->get_seqno(ring, false);
- ),
-
- TP_printk("dev=%u, ring=%u, seqno=%u",
- __entry->dev, __entry->ring, __entry->seqno)
+DEFINE_EVENT(i915_gem_request, i915_gem_request_complete,
+ TP_PROTO(struct intel_ring_buffer *ring, u32 seqno),
+ TP_ARGS(ring, seqno)
);
DEFINE_EVENT(i915_gem_request, i915_gem_request_retire,
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
index dfff090..57fe1ae 100644
--- a/drivers/gpu/drm/i915/intel_acpi.c
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -193,14 +193,16 @@ out:
static bool intel_dsm_pci_probe(struct pci_dev *pdev)
{
- acpi_handle dhandle;
+ acpi_handle dhandle, intel_handle;
+ acpi_status status;
int ret;
- dhandle = ACPI_HANDLE(&pdev->dev);
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
return false;
- if (!acpi_has_method(dhandle, "_DSM")) {
+ status = acpi_get_handle(dhandle, "_DSM", &intel_handle);
+ if (ACPI_FAILURE(status)) {
DRM_DEBUG_KMS("no _DSM method for intel device\n");
return false;
}
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index e4fba39..53f2bed 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -389,7 +389,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
{
struct sdvo_device_mapping *p_mapping;
struct bdb_general_definitions *p_defs;
- union child_device_config *p_child;
+ struct child_device_config *p_child;
int i, child_device_num, count;
u16 block_size;
@@ -416,36 +416,36 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
count = 0;
for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]);
- if (!p_child->old.device_type) {
+ if (!p_child->device_type) {
/* skip the device block if device type is invalid */
continue;
}
- if (p_child->old.slave_addr != SLAVE_ADDR1 &&
- p_child->old.slave_addr != SLAVE_ADDR2) {
+ if (p_child->slave_addr != SLAVE_ADDR1 &&
+ p_child->slave_addr != SLAVE_ADDR2) {
/*
* If the slave address is neither 0x70 nor 0x72,
* it is not a SDVO device. Skip it.
*/
continue;
}
- if (p_child->old.dvo_port != DEVICE_PORT_DVOB &&
- p_child->old.dvo_port != DEVICE_PORT_DVOC) {
+ if (p_child->dvo_port != DEVICE_PORT_DVOB &&
+ p_child->dvo_port != DEVICE_PORT_DVOC) {
/* skip the incorrect SDVO port */
DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
continue;
}
DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
" %s port\n",
- p_child->old.slave_addr,
- (p_child->old.dvo_port == DEVICE_PORT_DVOB) ?
+ p_child->slave_addr,
+ (p_child->dvo_port == DEVICE_PORT_DVOB) ?
"SDVOB" : "SDVOC");
- p_mapping = &(dev_priv->sdvo_mappings[p_child->old.dvo_port - 1]);
+ p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);
if (!p_mapping->initialized) {
- p_mapping->dvo_port = p_child->old.dvo_port;
- p_mapping->slave_addr = p_child->old.slave_addr;
- p_mapping->dvo_wiring = p_child->old.dvo_wiring;
- p_mapping->ddc_pin = p_child->old.ddc_pin;
- p_mapping->i2c_pin = p_child->old.i2c_pin;
+ p_mapping->dvo_port = p_child->dvo_port;
+ p_mapping->slave_addr = p_child->slave_addr;
+ p_mapping->dvo_wiring = p_child->dvo_wiring;
+ p_mapping->ddc_pin = p_child->ddc_pin;
+ p_mapping->i2c_pin = p_child->i2c_pin;
p_mapping->initialized = 1;
DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
p_mapping->dvo_port,
@@ -457,7 +457,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
"two SDVO device.\n");
}
- if (p_child->old.slave2_addr) {
+ if (p_child->slave2_addr) {
/* Maybe this is a SDVO device with multiple inputs */
/* And the mapping info is not added */
DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
@@ -477,13 +477,15 @@ static void
parse_driver_features(struct drm_i915_private *dev_priv,
struct bdb_header *bdb)
{
+ struct drm_device *dev = dev_priv->dev;
struct bdb_driver_features *driver;
driver = find_section(bdb, BDB_DRIVER_FEATURES);
if (!driver)
return;
- if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
+ if (SUPPORTS_EDP(dev) &&
+ driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
dev_priv->vbt.edp_support = 1;
if (driver->dual_frequency)
@@ -499,7 +501,7 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
edp = find_section(bdb, BDB_EDP);
if (!edp) {
- if (dev_priv->vbt.edp_support)
+ if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->vbt.edp_support)
DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
return;
}
@@ -567,149 +569,11 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
}
static void
-parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
-{
- struct bdb_mipi *mipi;
-
- mipi = find_section(bdb, BDB_MIPI);
- if (!mipi) {
- DRM_DEBUG_KMS("No MIPI BDB found");
- return;
- }
-
- /* XXX: add more info */
- dev_priv->vbt.dsi.panel_id = mipi->panel_id;
-}
-
-static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
- struct bdb_header *bdb)
-{
- union child_device_config *it, *child = NULL;
- struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port];
- uint8_t hdmi_level_shift;
- int i, j;
- bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
- uint8_t aux_channel;
- /* Each DDI port can have more than one value on the "DVO Port" field,
- * so look for all the possible values for each port and abort if more
- * than one is found. */
- int dvo_ports[][2] = {
- {DVO_PORT_HDMIA, DVO_PORT_DPA},
- {DVO_PORT_HDMIB, DVO_PORT_DPB},
- {DVO_PORT_HDMIC, DVO_PORT_DPC},
- {DVO_PORT_HDMID, DVO_PORT_DPD},
- {DVO_PORT_CRT, -1 /* Port E can only be DVO_PORT_CRT */ },
- };
-
- /* Find the child device to use, abort if more than one found. */
- for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
- it = dev_priv->vbt.child_dev + i;
-
- for (j = 0; j < 2; j++) {
- if (dvo_ports[port][j] == -1)
- break;
-
- if (it->common.dvo_port == dvo_ports[port][j]) {
- if (child) {
- DRM_DEBUG_KMS("More than one child device for port %c in VBT.\n",
- port_name(port));
- return;
- }
- child = it;
- }
- }
- }
- if (!child)
- return;
-
- aux_channel = child->raw[25];
-
- is_dvi = child->common.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
- is_dp = child->common.device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
- is_crt = child->common.device_type & DEVICE_TYPE_ANALOG_OUTPUT;
- is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0;
- is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR);
-
- info->supports_dvi = is_dvi;
- info->supports_hdmi = is_hdmi;
- info->supports_dp = is_dp;
-
- DRM_DEBUG_KMS("Port %c VBT info: DP:%d HDMI:%d DVI:%d EDP:%d CRT:%d\n",
- port_name(port), is_dp, is_hdmi, is_dvi, is_edp, is_crt);
-
- if (is_edp && is_dvi)
- DRM_DEBUG_KMS("Internal DP port %c is TMDS compatible\n",
- port_name(port));
- if (is_crt && port != PORT_E)
- DRM_DEBUG_KMS("Port %c is analog\n", port_name(port));
- if (is_crt && (is_dvi || is_dp))
- DRM_DEBUG_KMS("Analog port %c is also DP or TMDS compatible\n",
- port_name(port));
- if (is_dvi && (port == PORT_A || port == PORT_E))
- DRM_DEBUG_KMS("Port %c is TMDS compabile\n", port_name(port));
- if (!is_dvi && !is_dp && !is_crt)
- DRM_DEBUG_KMS("Port %c is not DP/TMDS/CRT compatible\n",
- port_name(port));
- if (is_edp && (port == PORT_B || port == PORT_C || port == PORT_E))
- DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
-
- if (is_dvi) {
- if (child->common.ddc_pin == 0x05 && port != PORT_B)
- DRM_DEBUG_KMS("Unexpected DDC pin for port B\n");
- if (child->common.ddc_pin == 0x04 && port != PORT_C)
- DRM_DEBUG_KMS("Unexpected DDC pin for port C\n");
- if (child->common.ddc_pin == 0x06 && port != PORT_D)
- DRM_DEBUG_KMS("Unexpected DDC pin for port D\n");
- }
-
- if (is_dp) {
- if (aux_channel == 0x40 && port != PORT_A)
- DRM_DEBUG_KMS("Unexpected AUX channel for port A\n");
- if (aux_channel == 0x10 && port != PORT_B)
- DRM_DEBUG_KMS("Unexpected AUX channel for port B\n");
- if (aux_channel == 0x20 && port != PORT_C)
- DRM_DEBUG_KMS("Unexpected AUX channel for port C\n");
- if (aux_channel == 0x30 && port != PORT_D)
- DRM_DEBUG_KMS("Unexpected AUX channel for port D\n");
- }
-
- if (bdb->version >= 158) {
- /* The VBT HDMI level shift values match the table we have. */
- hdmi_level_shift = child->raw[7] & 0xF;
- if (hdmi_level_shift < 0xC) {
- DRM_DEBUG_KMS("VBT HDMI level shift for port %c: %d\n",
- port_name(port),
- hdmi_level_shift);
- info->hdmi_level_shift = hdmi_level_shift;
- }
- }
-}
-
-static void parse_ddi_ports(struct drm_i915_private *dev_priv,
- struct bdb_header *bdb)
-{
- struct drm_device *dev = dev_priv->dev;
- enum port port;
-
- if (!HAS_DDI(dev))
- return;
-
- if (!dev_priv->vbt.child_dev_num)
- return;
-
- if (bdb->version < 155)
- return;
-
- for (port = PORT_A; port < I915_MAX_PORTS; port++)
- parse_ddi_port(dev_priv, port, bdb);
-}
-
-static void
parse_device_mapping(struct drm_i915_private *dev_priv,
struct bdb_header *bdb)
{
struct bdb_general_definitions *p_defs;
- union child_device_config *p_child, *child_dev_ptr;
+ struct child_device_config *p_child, *child_dev_ptr;
int i, child_device_num, count;
u16 block_size;
@@ -737,7 +601,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
/* get the number of child device that is present */
for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]);
- if (!p_child->common.device_type) {
+ if (!p_child->device_type) {
/* skip the device block if device type is invalid */
continue;
}
@@ -757,7 +621,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
count = 0;
for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]);
- if (!p_child->common.device_type) {
+ if (!p_child->device_type) {
/* skip the device block if device type is invalid */
continue;
}
@@ -773,7 +637,6 @@ static void
init_vbt_defaults(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
- enum port port;
dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC;
@@ -790,25 +653,8 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
/* Default to using SSC */
dev_priv->vbt.lvds_use_ssc = 1;
- /*
- * Core/SandyBridge/IvyBridge use alternative (120MHz) reference
- * clock for LVDS.
- */
- dev_priv->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(dev,
- !HAS_PCH_SPLIT(dev));
+ dev_priv->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->vbt.lvds_ssc_freq);
-
- for (port = PORT_A; port < I915_MAX_PORTS; port++) {
- struct ddi_vbt_port_info *info =
- &dev_priv->vbt.ddi_port_info[port];
-
- /* Recommended BSpec default: 800mV 0dB. */
- info->hdmi_level_shift = 6;
-
- info->supports_dvi = (port != PORT_A && port != PORT_E);
- info->supports_hdmi = info->supports_dvi;
- info->supports_dp = (port != PORT_E);
- }
}
static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
@@ -899,8 +745,6 @@ intel_parse_bios(struct drm_device *dev)
parse_device_mapping(dev_priv, bdb);
parse_driver_features(dev_priv, bdb);
parse_edp(dev_priv, bdb);
- parse_mipi(dev_priv, bdb);
- parse_ddi_ports(dev_priv, bdb);
if (bios)
pci_unmap_rom(pdev, bios);
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index f580a2b..e088d6f 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -104,7 +104,6 @@ struct vbios_data {
#define BDB_LVDS_LFP_DATA 42
#define BDB_LVDS_BACKLIGHT 43
#define BDB_LVDS_POWER 44
-#define BDB_MIPI 50
#define BDB_SKIP 254 /* VBIOS private block, ignore */
struct bdb_general_features {
@@ -202,10 +201,7 @@ struct bdb_general_features {
#define DEVICE_PORT_DVOB 0x01
#define DEVICE_PORT_DVOC 0x02
-/* We used to keep this struct but without any version control. We should avoid
- * using it in the future, but it should be safe to keep using it in the old
- * code. */
-struct old_child_dev_config {
+struct child_device_config {
u16 handle;
u16 device_type;
u8 device_id[10]; /* ascii string */
@@ -227,32 +223,6 @@ struct old_child_dev_config {
u8 dvo_function;
} __attribute__((packed));
-/* This one contains field offsets that are known to be common for all BDB
- * versions. Notice that the meaning of the contents contents may still change,
- * but at least the offsets are consistent. */
-struct common_child_dev_config {
- u16 handle;
- u16 device_type;
- u8 not_common1[12];
- u8 dvo_port;
- u8 not_common2[2];
- u8 ddc_pin;
- u16 edid_ptr;
-} __attribute__((packed));
-
-/* This field changes depending on the BDB version, so the most reliable way to
- * read it is by checking the BDB version and reading the raw pointer. */
-union child_device_config {
- /* This one is safe to be used anywhere, but the code should still check
- * the BDB version. */
- u8 raw[33];
- /* This one should only be kept for legacy code. */
- struct old_child_dev_config old;
- /* This one should also be safe to use anywhere, even without version
- * checks. */
- struct common_child_dev_config common;
-};
-
struct bdb_general_definitions {
/* DDC GPIO */
u8 crt_ddc_gmbus_pin;
@@ -278,7 +248,7 @@ struct bdb_general_definitions {
* number = (block_size - sizeof(bdb_general_definitions))/
* sizeof(child_device_config);
*/
- union child_device_config devices[0];
+ struct child_device_config devices[0];
} __attribute__((packed));
struct bdb_lvds_options {
@@ -638,40 +608,6 @@ int intel_parse_bios(struct drm_device *dev);
#define DEVICE_TYPE_DP 0x68C6
#define DEVICE_TYPE_eDP 0x78C6
-#define DEVICE_TYPE_CLASS_EXTENSION (1 << 15)
-#define DEVICE_TYPE_POWER_MANAGEMENT (1 << 14)
-#define DEVICE_TYPE_HOTPLUG_SIGNALING (1 << 13)
-#define DEVICE_TYPE_INTERNAL_CONNECTOR (1 << 12)
-#define DEVICE_TYPE_NOT_HDMI_OUTPUT (1 << 11)
-#define DEVICE_TYPE_MIPI_OUTPUT (1 << 10)
-#define DEVICE_TYPE_COMPOSITE_OUTPUT (1 << 9)
-#define DEVICE_TYPE_DUAL_CHANNEL (1 << 8)
-#define DEVICE_TYPE_HIGH_SPEED_LINK (1 << 6)
-#define DEVICE_TYPE_LVDS_SINGALING (1 << 5)
-#define DEVICE_TYPE_TMDS_DVI_SIGNALING (1 << 4)
-#define DEVICE_TYPE_VIDEO_SIGNALING (1 << 3)
-#define DEVICE_TYPE_DISPLAYPORT_OUTPUT (1 << 2)
-#define DEVICE_TYPE_DIGITAL_OUTPUT (1 << 1)
-#define DEVICE_TYPE_ANALOG_OUTPUT (1 << 0)
-
-/*
- * Bits we care about when checking for DEVICE_TYPE_eDP
- * Depending on the system, the other bits may or may not
- * be set for eDP outputs.
- */
-#define DEVICE_TYPE_eDP_BITS \
- (DEVICE_TYPE_INTERNAL_CONNECTOR | \
- DEVICE_TYPE_NOT_HDMI_OUTPUT | \
- DEVICE_TYPE_MIPI_OUTPUT | \
- DEVICE_TYPE_COMPOSITE_OUTPUT | \
- DEVICE_TYPE_DUAL_CHANNEL | \
- DEVICE_TYPE_LVDS_SINGALING | \
- DEVICE_TYPE_TMDS_DVI_SIGNALING | \
- DEVICE_TYPE_VIDEO_SIGNALING | \
- DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
- DEVICE_TYPE_DIGITAL_OUTPUT | \
- DEVICE_TYPE_ANALOG_OUTPUT)
-
/* define the DVO port for HDMI output type */
#define DVO_B 1
#define DVO_C 2
@@ -682,57 +618,4 @@ int intel_parse_bios(struct drm_device *dev);
#define PORT_IDPC 8
#define PORT_IDPD 9
-/* Possible values for the "DVO Port" field for versions >= 155: */
-#define DVO_PORT_HDMIA 0
-#define DVO_PORT_HDMIB 1
-#define DVO_PORT_HDMIC 2
-#define DVO_PORT_HDMID 3
-#define DVO_PORT_LVDS 4
-#define DVO_PORT_TV 5
-#define DVO_PORT_CRT 6
-#define DVO_PORT_DPB 7
-#define DVO_PORT_DPC 8
-#define DVO_PORT_DPD 9
-#define DVO_PORT_DPA 10
-
-/* MIPI DSI panel info */
-struct bdb_mipi {
- u16 panel_id;
- u16 bridge_revision;
-
- /* General params */
- u32 dithering:1;
- u32 bpp_pixel_format:1;
- u32 rsvd1:1;
- u32 dphy_valid:1;
- u32 resvd2:28;
-
- u16 port_info;
- u16 rsvd3:2;
- u16 num_lanes:2;
- u16 rsvd4:12;
-
- /* DSI config */
- u16 virt_ch_num:2;
- u16 vtm:2;
- u16 rsvd5:12;
-
- u32 dsi_clock;
- u32 bridge_ref_clk;
- u16 rsvd_pwr;
-
- /* Dphy Params */
- u32 prepare_cnt:5;
- u32 rsvd6:3;
- u32 clk_zero_cnt:8;
- u32 trail_cnt:5;
- u32 rsvd7:3;
- u32 exit_zero_cnt:6;
- u32 rsvd8:2;
-
- u32 hl_switch_cnt;
- u32 lp_byte_clk;
- u32 clk_lane_switch_cnt;
-} __attribute__((packed));
-
#endif /* _I830_BIOS_H_ */
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index b5b1b9b..10d1de5 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -107,17 +107,7 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
static void intel_crt_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
- struct drm_device *dev = encoder->base.dev;
- int dotclock;
-
pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder);
-
- dotclock = pipe_config->port_clock;
-
- if (HAS_PCH_SPLIT(dev))
- ironlake_check_encoder_dotclock(pipe_config, dotclock);
-
- pipe_config->adjusted_mode.crtc_clock = dotclock;
}
static void hsw_crt_get_config(struct intel_encoder *encoder,
@@ -274,7 +264,7 @@ static void intel_crt_mode_set(struct intel_encoder *encoder)
struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode;
u32 adpa;
- if (INTEL_INFO(dev)->gen >= 5)
+ if (HAS_PCH_SPLIT(dev))
adpa = ADPA_HOTPLUG_BITS;
else
adpa = 0;
@@ -376,6 +366,9 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
DRM_DEBUG_KMS("valleyview hotplug adpa=0x%x, result %d\n", adpa, ret);
+ /* FIXME: debug force function and remove */
+ ret = true;
+
return ret;
}
@@ -677,6 +670,7 @@ intel_crt_detect(struct drm_connector *connector, bool force)
static void intel_crt_destroy(struct drm_connector *connector)
{
+ drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -782,7 +776,7 @@ void intel_crt_init(struct drm_device *dev)
if (!crt)
return;
- intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+ intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(crt);
return;
@@ -822,15 +816,16 @@ void intel_crt_init(struct drm_device *dev)
crt->base.mode_set = intel_crt_mode_set;
crt->base.disable = intel_disable_crt;
crt->base.enable = intel_enable_crt;
+ if (IS_HASWELL(dev))
+ crt->base.get_config = hsw_crt_get_config;
+ else
+ crt->base.get_config = intel_crt_get_config;
if (I915_HAS_HOTPLUG(dev))
crt->base.hpd_pin = HPD_CRT;
- if (HAS_DDI(dev)) {
- crt->base.get_config = hsw_crt_get_config;
+ if (HAS_DDI(dev))
crt->base.get_hw_state = intel_ddi_get_hw_state;
- } else {
- crt->base.get_config = intel_crt_get_config;
+ else
crt->base.get_hw_state = intel_crt_get_hw_state;
- }
intel_connector->get_hw_state = intel_connector_get_hw_state;
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 526c8de..b53fff8 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -42,6 +42,7 @@ static const u32 hsw_ddi_translations_dp[] = {
0x80C30FFF, 0x000B0000,
0x00FFFFFF, 0x00040006,
0x80D75FFF, 0x000B0000,
+ 0x00FFFFFF, 0x00040006 /* HDMI parameters */
};
static const u32 hsw_ddi_translations_fdi[] = {
@@ -54,64 +55,10 @@ static const u32 hsw_ddi_translations_fdi[] = {
0x00C30FFF, 0x001E0000,
0x00FFFFFF, 0x00060006,
0x00D75FFF, 0x001E0000,
+ 0x00FFFFFF, 0x00040006 /* HDMI parameters */
};
-static const u32 hsw_ddi_translations_hdmi[] = {
- /* Idx NT mV diff T mV diff db */
- 0x00FFFFFF, 0x0006000E, /* 0: 400 400 0 */
- 0x00E79FFF, 0x000E000C, /* 1: 400 500 2 */
- 0x00D75FFF, 0x0005000A, /* 2: 400 600 3.5 */
- 0x00FFFFFF, 0x0005000A, /* 3: 600 600 0 */
- 0x00E79FFF, 0x001D0007, /* 4: 600 750 2 */
- 0x00D75FFF, 0x000C0004, /* 5: 600 900 3.5 */
- 0x00FFFFFF, 0x00040006, /* 6: 800 800 0 */
- 0x80E79FFF, 0x00030002, /* 7: 800 1000 2 */
- 0x00FFFFFF, 0x00140005, /* 8: 850 850 0 */
- 0x00FFFFFF, 0x000C0004, /* 9: 900 900 0 */
- 0x00FFFFFF, 0x001C0003, /* 10: 950 950 0 */
- 0x80FFFFFF, 0x00030002, /* 11: 1000 1000 0 */
-};
-
-static const u32 bdw_ddi_translations_edp[] = {
- 0x00FFFFFF, 0x00000012, /* DP parameters */
- 0x00EBAFFF, 0x00020011,
- 0x00C71FFF, 0x0006000F,
- 0x00FFFFFF, 0x00020011,
- 0x00DB6FFF, 0x0005000F,
- 0x00BEEFFF, 0x000A000C,
- 0x00FFFFFF, 0x0005000F,
- 0x00DB6FFF, 0x000A000C,
- 0x00FFFFFF, 0x000A000C,
- 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
-};
-
-static const u32 bdw_ddi_translations_dp[] = {
- 0x00FFFFFF, 0x0007000E, /* DP parameters */
- 0x00D75FFF, 0x000E000A,
- 0x00BEFFFF, 0x00140006,
- 0x00FFFFFF, 0x000E000A,
- 0x00D75FFF, 0x00180004,
- 0x80CB2FFF, 0x001B0002,
- 0x00F7DFFF, 0x00180004,
- 0x80D75FFF, 0x001B0002,
- 0x80FFFFFF, 0x001B0002,
- 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
-};
-
-static const u32 bdw_ddi_translations_fdi[] = {
- 0x00FFFFFF, 0x0001000E, /* FDI parameters */
- 0x00D75FFF, 0x0004000A,
- 0x00C30FFF, 0x00070006,
- 0x00AAAFFF, 0x000C0000,
- 0x00FFFFFF, 0x0004000A,
- 0x00D75FFF, 0x00090004,
- 0x00C30FFF, 0x000C0000,
- 0x00FFFFFF, 0x00070006,
- 0x00D75FFF, 0x000C0000,
- 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
-};
-
-enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
+static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
{
struct drm_encoder *encoder = &intel_encoder->base;
int type = intel_encoder->type;
@@ -131,9 +78,8 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
}
}
-/*
- * Starting with Haswell, DDI port buffers must be programmed with correct
- * values in advance. The buffer values are different for FDI and DP modes,
+/* On Haswell, DDI port buffers must be programmed with correct values
+ * in advance. The buffer values are different for FDI and DP modes,
* but the HDMI/DVI fields are shared among those. So we program the DDI
* in either FDI or DP modes only, as HDMI connections will work with both
* of those
@@ -143,58 +89,15 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg;
int i;
- int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
- const u32 *ddi_translations_fdi;
- const u32 *ddi_translations_dp;
- const u32 *ddi_translations_edp;
- const u32 *ddi_translations;
-
- if (IS_BROADWELL(dev)) {
- ddi_translations_fdi = bdw_ddi_translations_fdi;
- ddi_translations_dp = bdw_ddi_translations_dp;
- ddi_translations_edp = bdw_ddi_translations_edp;
- } else if (IS_HASWELL(dev)) {
- ddi_translations_fdi = hsw_ddi_translations_fdi;
- ddi_translations_dp = hsw_ddi_translations_dp;
- ddi_translations_edp = hsw_ddi_translations_dp;
- } else {
- WARN(1, "ddi translation table missing\n");
- ddi_translations_edp = bdw_ddi_translations_dp;
- ddi_translations_fdi = bdw_ddi_translations_fdi;
- ddi_translations_dp = bdw_ddi_translations_dp;
- }
-
- switch (port) {
- case PORT_A:
- ddi_translations = ddi_translations_edp;
- break;
- case PORT_B:
- case PORT_C:
- ddi_translations = ddi_translations_dp;
- break;
- case PORT_D:
- if (intel_dp_is_edp(dev, PORT_D))
- ddi_translations = ddi_translations_edp;
- else
- ddi_translations = ddi_translations_dp;
- break;
- case PORT_E:
- ddi_translations = ddi_translations_fdi;
- break;
- default:
- BUG();
- }
+ const u32 *ddi_translations = (port == PORT_E) ?
+ hsw_ddi_translations_fdi :
+ hsw_ddi_translations_dp;
for (i = 0, reg = DDI_BUF_TRANS(port);
i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) {
I915_WRITE(reg, ddi_translations[i]);
reg += 4;
}
- /* Entry 9 is for HDMI: */
- for (i = 0; i < 2; i++) {
- I915_WRITE(reg, hsw_ddi_translations_hdmi[hdmi_level * 2 + i]);
- reg += 4;
- }
}
/* Program DDI buffers translations for DP. By default, program ports A-D in DP
@@ -393,6 +296,9 @@ static void intel_ddi_mode_set(struct intel_encoder *encoder)
DRM_DEBUG_DRIVER("DP audio: write eld information\n");
intel_write_eld(&encoder->base, adjusted_mode);
}
+
+ intel_dp_init_link_config(intel_dp);
+
} else if (type == INTEL_OUTPUT_HDMI) {
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
@@ -833,8 +739,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
struct drm_encoder *encoder = &intel_encoder->base;
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = crtc->dev->dev_private;
enum pipe pipe = intel_crtc->pipe;
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
enum port port = intel_ddi_get_encoder_port(intel_encoder);
@@ -862,19 +767,18 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
BUG();
}
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
+ if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
temp |= TRANS_DDI_PVSYNC;
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
+ if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
temp |= TRANS_DDI_PHSYNC;
if (cpu_transcoder == TRANSCODER_EDP) {
switch (pipe) {
case PIPE_A:
- /* On Haswell, can only use the always-on power well for
- * eDP when not using the panel fitter, and when not
- * using motion blur mitigation (which we don't
- * support). */
- if (IS_HASWELL(dev) && intel_crtc->config.pch_pfit.enabled)
+ /* Can only use the always-on power well for eDP when
+ * not using the panel fitter, and when not using motion
+ * blur mitigation (which we don't support). */
+ if (intel_crtc->config.pch_pfit.enabled)
temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
else
temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1158,10 +1062,9 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
if (wait)
intel_wait_ddi_buf_idle(dev_priv, port);
- if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
+ if (type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
ironlake_edp_panel_vdd_on(intel_dp);
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
ironlake_edp_panel_off(intel_dp);
}
@@ -1236,29 +1139,18 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
{
- struct drm_device *dev = dev_priv->dev;
uint32_t lcpll = I915_READ(LCPLL_CTL);
- uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
- if (lcpll & LCPLL_CD_SOURCE_FCLK) {
+ if (lcpll & LCPLL_CD_SOURCE_FCLK)
return 800000;
- } else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) {
+ else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT)
return 450000;
- } else if (freq == LCPLL_CLK_FREQ_450) {
+ else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450)
return 450000;
- } else if (IS_HASWELL(dev)) {
- if (IS_ULT(dev))
- return 337500;
- else
- return 540000;
- } else {
- if (freq == LCPLL_CLK_FREQ_54O_BDW)
- return 540000;
- else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
- return 337500;
- else
- return 675000;
- }
+ else if (IS_ULT(dev_priv->dev))
+ return 337500;
+ else
+ return 540000;
}
void intel_ddi_pll_init(struct drm_device *dev)
@@ -1310,7 +1202,7 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST |
DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
- if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+ if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
I915_WRITE(DP_TP_CTL(port), val);
POSTING_READ(DP_TP_CTL(port));
@@ -1393,40 +1285,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
default:
break;
}
-
- switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
- case TRANS_DDI_MODE_SELECT_HDMI:
- case TRANS_DDI_MODE_SELECT_DVI:
- case TRANS_DDI_MODE_SELECT_FDI:
- break;
- case TRANS_DDI_MODE_SELECT_DP_SST:
- case TRANS_DDI_MODE_SELECT_DP_MST:
- pipe_config->has_dp_encoder = true;
- intel_dp_get_m_n(intel_crtc, pipe_config);
- break;
- default:
- break;
- }
-
- if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
- pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
- /*
- * This is a big fat ugly hack.
- *
- * Some machines in UEFI boot mode provide us a VBT that has 18
- * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
- * unknown we fail to light up. Yet the same BIOS boots up with
- * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
- * max, not what it tells us to use.
- *
- * Note: This will still be broken if the eDP panel is not lit
- * up by the BIOS, and thus we can't get the mode at module
- * load.
- */
- DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
- pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
- dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
- }
}
static void intel_ddi_destroy(struct drm_encoder *encoder)
@@ -1456,41 +1314,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {
.destroy = intel_ddi_destroy,
};
-static struct intel_connector *
-intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
-{
- struct intel_connector *connector;
- enum port port = intel_dig_port->port;
-
- connector = kzalloc(sizeof(*connector), GFP_KERNEL);
- if (!connector)
- return NULL;
-
- intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
- if (!intel_dp_init_connector(intel_dig_port, connector)) {
- kfree(connector);
- return NULL;
- }
-
- return connector;
-}
-
-static struct intel_connector *
-intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
-{
- struct intel_connector *connector;
- enum port port = intel_dig_port->port;
-
- connector = kzalloc(sizeof(*connector), GFP_KERNEL);
- if (!connector)
- return NULL;
-
- intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
- intel_hdmi_init_connector(intel_dig_port, connector);
-
- return connector;
-}
-
void intel_ddi_init(struct drm_device *dev, enum port port)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1499,22 +1322,17 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
struct drm_encoder *encoder;
struct intel_connector *hdmi_connector = NULL;
struct intel_connector *dp_connector = NULL;
- bool init_hdmi, init_dp;
-
- init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
- dev_priv->vbt.ddi_port_info[port].supports_hdmi);
- init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
- if (!init_dp && !init_hdmi) {
- DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible\n",
- port_name(port));
- init_hdmi = true;
- init_dp = true;
- }
- intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
+ intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
if (!intel_dig_port)
return;
+ dp_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
+ if (!dp_connector) {
+ kfree(intel_dig_port);
+ return;
+ }
+
intel_encoder = &intel_dig_port->base;
encoder = &intel_encoder->base;
@@ -1534,22 +1352,28 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
(DDI_BUF_PORT_REVERSAL |
DDI_A_4_LANES);
+ intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->cloneable = false;
intel_encoder->hot_plug = intel_ddi_hot_plug;
- if (init_dp)
- dp_connector = intel_ddi_init_dp_connector(intel_dig_port);
-
- /* In theory we don't need the encoder->type check, but leave it just in
- * case we have some really bad VBTs... */
- if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi)
- hdmi_connector = intel_ddi_init_hdmi_connector(intel_dig_port);
-
- if (!dp_connector && !hdmi_connector) {
+ if (!intel_dp_init_connector(intel_dig_port, dp_connector)) {
drm_encoder_cleanup(encoder);
kfree(intel_dig_port);
+ kfree(dp_connector);
+ return;
+ }
+
+ if (intel_encoder->type != INTEL_OUTPUT_EDP) {
+ hdmi_connector = kzalloc(sizeof(struct intel_connector),
+ GFP_KERNEL);
+ if (!hdmi_connector) {
+ return;
+ }
+
+ intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
+ intel_hdmi_init_connector(intel_dig_port, hdmi_connector);
}
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 080f6fd..d78d33f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -41,13 +41,14 @@
#include <drm/drm_crtc_helper.h>
#include <linux/dma_remapping.h>
+bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
static void intel_increase_pllclock(struct drm_crtc *crtc);
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config);
-static void ironlake_pch_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config);
+static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config);
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
int x, int y, struct drm_framebuffer *old_fb);
@@ -68,6 +69,9 @@ struct intel_limit {
intel_p2_t p2;
};
+/* FDI */
+#define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */
+
int
intel_pch_rawclk(struct drm_device *dev)
{
@@ -309,44 +313,44 @@ static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
.p2_slow = 7, .p2_fast = 7 },
};
-static const intel_limit_t intel_limits_vlv = {
- /*
- * These are the data rate limits (measured in fast clocks)
- * since those are the strictest limits we have. The fast
- * clock and actual rate limits are more relaxed, so checking
- * them would make no difference.
- */
- .dot = { .min = 25000 * 5, .max = 270000 * 5 },
+static const intel_limit_t intel_limits_vlv_dac = {
+ .dot = { .min = 25000, .max = 270000 },
.vco = { .min = 4000000, .max = 6000000 },
.n = { .min = 1, .max = 7 },
+ .m = { .min = 22, .max = 450 }, /* guess */
.m1 = { .min = 2, .max = 3 },
.m2 = { .min = 11, .max = 156 },
- .p1 = { .min = 2, .max = 3 },
- .p2 = { .p2_slow = 2, .p2_fast = 20 }, /* slow=min, fast=max */
+ .p = { .min = 10, .max = 30 },
+ .p1 = { .min = 1, .max = 3 },
+ .p2 = { .dot_limit = 270000,
+ .p2_slow = 2, .p2_fast = 20 },
};
-static void vlv_clock(int refclk, intel_clock_t *clock)
-{
- clock->m = clock->m1 * clock->m2;
- clock->p = clock->p1 * clock->p2;
- clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
- clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
-}
-
-/**
- * Returns whether any output on the specified pipe is of the specified type
- */
-static bool intel_pipe_has_type(struct drm_crtc *crtc, int type)
-{
- struct drm_device *dev = crtc->dev;
- struct intel_encoder *encoder;
-
- for_each_encoder_on_crtc(dev, crtc, encoder)
- if (encoder->type == type)
- return true;
+static const intel_limit_t intel_limits_vlv_hdmi = {
+ .dot = { .min = 25000, .max = 270000 },
+ .vco = { .min = 4000000, .max = 6000000 },
+ .n = { .min = 1, .max = 7 },
+ .m = { .min = 60, .max = 300 }, /* guess */
+ .m1 = { .min = 2, .max = 3 },
+ .m2 = { .min = 11, .max = 156 },
+ .p = { .min = 10, .max = 30 },
+ .p1 = { .min = 2, .max = 3 },
+ .p2 = { .dot_limit = 270000,
+ .p2_slow = 2, .p2_fast = 20 },
+};
- return false;
-}
+static const intel_limit_t intel_limits_vlv_dp = {
+ .dot = { .min = 25000, .max = 270000 },
+ .vco = { .min = 4000000, .max = 6000000 },
+ .n = { .min = 1, .max = 7 },
+ .m = { .min = 22, .max = 450 },
+ .m1 = { .min = 2, .max = 3 },
+ .m2 = { .min = 11, .max = 156 },
+ .p = { .min = 10, .max = 30 },
+ .p1 = { .min = 1, .max = 3 },
+ .p2 = { .dot_limit = 270000,
+ .p2_slow = 2, .p2_fast = 20 },
+};
static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
int refclk)
@@ -408,7 +412,12 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk)
else
limit = &intel_limits_pineview_sdvo;
} else if (IS_VALLEYVIEW(dev)) {
- limit = &intel_limits_vlv;
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG))
+ limit = &intel_limits_vlv_dac;
+ else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
+ limit = &intel_limits_vlv_hdmi;
+ else
+ limit = &intel_limits_vlv_dp;
} else if (!IS_GEN2(dev)) {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
limit = &intel_limits_i9xx_lvds;
@@ -430,8 +439,8 @@ static void pineview_clock(int refclk, intel_clock_t *clock)
{
clock->m = clock->m2 + 2;
clock->p = clock->p1 * clock->p2;
- clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
- clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
+ clock->vco = refclk * clock->m / clock->n;
+ clock->dot = clock->vco / clock->p;
}
static uint32_t i9xx_dpll_compute_m(struct dpll *dpll)
@@ -443,8 +452,23 @@ static void i9xx_clock(int refclk, intel_clock_t *clock)
{
clock->m = i9xx_dpll_compute_m(clock);
clock->p = clock->p1 * clock->p2;
- clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);
- clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
+ clock->vco = refclk * clock->m / (clock->n + 2);
+ clock->dot = clock->vco / clock->p;
+}
+
+/**
+ * Returns whether any output on the specified pipe is of the specified type
+ */
+bool intel_pipe_has_type(struct drm_crtc *crtc, int type)
+{
+ struct drm_device *dev = crtc->dev;
+ struct intel_encoder *encoder;
+
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ if (encoder->type == type)
+ return true;
+
+ return false;
}
#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0)
@@ -457,26 +481,20 @@ static bool intel_PLL_is_valid(struct drm_device *dev,
const intel_limit_t *limit,
const intel_clock_t *clock)
{
- if (clock->n < limit->n.min || limit->n.max < clock->n)
- INTELPllInvalid("n out of range\n");
if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
INTELPllInvalid("p1 out of range\n");
+ if (clock->p < limit->p.min || limit->p.max < clock->p)
+ INTELPllInvalid("p out of range\n");
if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
INTELPllInvalid("m2 out of range\n");
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
INTELPllInvalid("m1 out of range\n");
-
- if (!IS_PINEVIEW(dev) && !IS_VALLEYVIEW(dev))
- if (clock->m1 <= clock->m2)
- INTELPllInvalid("m1 <= m2\n");
-
- if (!IS_VALLEYVIEW(dev)) {
- if (clock->p < limit->p.min || limit->p.max < clock->p)
- INTELPllInvalid("p out of range\n");
- if (clock->m < limit->m.min || limit->m.max < clock->m)
- INTELPllInvalid("m out of range\n");
- }
-
+ if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev))
+ INTELPllInvalid("m1 <= m2\n");
+ if (clock->m < limit->m.min || limit->m.max < clock->m)
+ INTELPllInvalid("m out of range\n");
+ if (clock->n < limit->n.min || limit->n.max < clock->n)
+ INTELPllInvalid("n out of range\n");
if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
INTELPllInvalid("vco out of range\n");
/* XXX: We may need to be checking "Dot clock" depending on the multiplier,
@@ -670,73 +688,67 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc,
int target, int refclk, intel_clock_t *match_clock,
intel_clock_t *best_clock)
{
- struct drm_device *dev = crtc->dev;
- intel_clock_t clock;
- unsigned int bestppm = 1000000;
- /* min update 19.2 MHz */
- int max_n = min(limit->n.max, refclk / 19200);
- bool found = false;
-
- target *= 5; /* fast clock */
-
- memset(best_clock, 0, sizeof(*best_clock));
+ u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2;
+ u32 m, n, fastclk;
+ u32 updrate, minupdate, p;
+ unsigned long bestppm, ppm, absppm;
+ int dotclk, flag;
+
+ flag = 0;
+ dotclk = target * 1000;
+ bestppm = 1000000;
+ ppm = absppm = 0;
+ fastclk = dotclk / (2*100);
+ updrate = 0;
+ minupdate = 19200;
+ n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0;
+ bestm1 = bestm2 = bestp1 = bestp2 = 0;
/* based on hardware requirement, prefer smaller n to precision */
- for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
- for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
- for (clock.p2 = limit->p2.p2_fast; clock.p2 >= limit->p2.p2_slow;
- clock.p2 -= clock.p2 > 10 ? 2 : 1) {
- clock.p = clock.p1 * clock.p2;
+ for (n = limit->n.min; n <= ((refclk) / minupdate); n++) {
+ updrate = refclk / n;
+ for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) {
+ for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) {
+ if (p2 > 10)
+ p2 = p2 - 1;
+ p = p1 * p2;
/* based on hardware requirement, prefer bigger m1,m2 values */
- for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
- unsigned int ppm, diff;
-
- clock.m2 = DIV_ROUND_CLOSEST(target * clock.p * clock.n,
- refclk * clock.m1);
-
- vlv_clock(refclk, &clock);
-
- if (!intel_PLL_is_valid(dev, limit,
- &clock))
- continue;
-
- diff = abs(clock.dot - target);
- ppm = div_u64(1000000ULL * diff, target);
-
- if (ppm < 100 && clock.p > best_clock->p) {
- bestppm = 0;
- *best_clock = clock;
- found = true;
- }
-
- if (bestppm >= 10 && ppm < bestppm - 10) {
- bestppm = ppm;
- *best_clock = clock;
- found = true;
+ for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) {
+ m2 = (((2*(fastclk * p * n / m1 )) +
+ refclk) / (2*refclk));
+ m = m1 * m2;
+ vco = updrate * m;
+ if (vco >= limit->vco.min && vco < limit->vco.max) {
+ ppm = 1000000 * ((vco / p) - fastclk) / fastclk;
+ absppm = (ppm > 0) ? ppm : (-ppm);
+ if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) {
+ bestppm = 0;
+ flag = 1;
+ }
+ if (absppm < bestppm - 10) {
+ bestppm = absppm;
+ flag = 1;
+ }
+ if (flag) {
+ bestn = n;
+ bestm1 = m1;
+ bestm2 = m2;
+ bestp1 = p1;
+ bestp2 = p2;
+ flag = 0;
+ }
}
}
}
}
}
+ best_clock->n = bestn;
+ best_clock->m1 = bestm1;
+ best_clock->m2 = bestm2;
+ best_clock->p1 = bestp1;
+ best_clock->p2 = bestp2;
- return found;
-}
-
-bool intel_crtc_active(struct drm_crtc *crtc)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- /* Be paranoid as we can arrive here with only partial
- * state retrieved from the hardware during setup.
- *
- * We can ditch the adjusted_mode.crtc_clock check as soon
- * as Haswell has gained clock readout/fastboot support.
- *
- * We can ditch the crtc->fb check as soon as we can
- * properly reconstruct framebuffers.
- */
- return intel_crtc->active && crtc->fb &&
- intel_crtc->config.adjusted_mode.crtc_clock;
+ return true;
}
enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
@@ -800,25 +812,6 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
DRM_DEBUG_KMS("vblank wait timed out\n");
}
-static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 reg = PIPEDSL(pipe);
- u32 line1, line2;
- u32 line_mask;
-
- if (IS_GEN2(dev))
- line_mask = DSL_LINEMASK_GEN2;
- else
- line_mask = DSL_LINEMASK_GEN3;
-
- line1 = I915_READ(reg) & line_mask;
- mdelay(5);
- line2 = I915_READ(reg) & line_mask;
-
- return line1 == line2;
-}
-
/*
* intel_wait_for_pipe_off - wait for pipe to turn off
* @dev: drm device
@@ -850,8 +843,22 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
100))
WARN(1, "pipe_off wait timed out\n");
} else {
+ u32 last_line, line_mask;
+ int reg = PIPEDSL(pipe);
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+ if (IS_GEN2(dev))
+ line_mask = DSL_LINEMASK_GEN2;
+ else
+ line_mask = DSL_LINEMASK_GEN3;
+
/* Wait for the display line to settle */
- if (wait_for(pipe_dsl_stopped(dev, pipe), 100))
+ do {
+ last_line = I915_READ(reg) & line_mask;
+ mdelay(5);
+ } while (((I915_READ(reg) & line_mask) != last_line) &&
+ time_after(timeout, jiffies));
+ if (time_after(jiffies, timeout))
WARN(1, "pipe_off wait timed out\n");
}
}
@@ -922,24 +929,6 @@ void assert_pll(struct drm_i915_private *dev_priv,
state_string(state), state_string(cur_state));
}
-/* XXX: the dsi pll is shared between MIPI DSI ports */
-static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
-{
- u32 val;
- bool cur_state;
-
- mutex_lock(&dev_priv->dpio_lock);
- val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
- mutex_unlock(&dev_priv->dpio_lock);
-
- cur_state = val & DSI_PLL_VCO_EN;
- WARN(cur_state != state,
- "DSI PLL state assertion failure (expected %s, current %s)\n",
- state_string(state), state_string(cur_state));
-}
-#define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
-#define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
-
struct intel_shared_dpll *
intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
{
@@ -1080,26 +1069,6 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
pipe_name(pipe));
}
-static void assert_cursor(struct drm_i915_private *dev_priv,
- enum pipe pipe, bool state)
-{
- struct drm_device *dev = dev_priv->dev;
- bool cur_state;
-
- if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
- cur_state = I915_READ(CURCNTR_IVB(pipe)) & CURSOR_MODE;
- else if (IS_845G(dev) || IS_I865G(dev))
- cur_state = I915_READ(_CURACNTR) & CURSOR_ENABLE;
- else
- cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
-
- WARN(cur_state != state,
- "cursor on pipe %c assertion failure (expected %s, current %s)\n",
- pipe_name(pipe), state_string(state), state_string(cur_state));
-}
-#define assert_cursor_enabled(d, p) assert_cursor(d, p, true)
-#define assert_cursor_disabled(d, p) assert_cursor(d, p, false)
-
void assert_pipe(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
@@ -1354,26 +1323,6 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
}
-static void intel_init_dpio(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (!IS_VALLEYVIEW(dev))
- return;
-
- /*
- * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
- * 6. De-assert cmn_reset/side_reset. Same as VLV X0.
- * a. GUnit 0x2110 bit[0] set to 1 (def 0)
- * b. The other bits such as sfr settings / modesel may all be set
- * to 0.
- *
- * This should only be done on init and resume from S3 with both
- * PLLs disabled, or we risk losing DPIO and PLL synchronization.
- */
- I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST);
-}
-
static void vlv_enable_pll(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
@@ -1480,20 +1429,6 @@ static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
POSTING_READ(DPLL(pipe));
}
-static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
-{
- u32 val = 0;
-
- /* Make sure the pipe isn't still relying on us */
- assert_pipe_disabled(dev_priv, pipe);
-
- /* Leave integrated clock source enabled */
- if (pipe == PIPE_B)
- val = DPLL_INTEGRATED_CRI_CLK_VLV;
- I915_WRITE(DPLL(pipe), val);
- POSTING_READ(DPLL(pipe));
-}
-
void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port)
{
u32 port_mask;
@@ -1726,7 +1661,7 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
* returning.
*/
static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
- bool pch_port, bool dsi)
+ bool pch_port)
{
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
pipe);
@@ -1735,7 +1670,6 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
u32 val;
assert_planes_disabled(dev_priv, pipe);
- assert_cursor_disabled(dev_priv, pipe);
assert_sprites_disabled(dev_priv, pipe);
if (HAS_PCH_LPT(dev_priv->dev))
@@ -1749,10 +1683,7 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
* need the check.
*/
if (!HAS_PCH_SPLIT(dev_priv->dev))
- if (dsi)
- assert_dsi_pll_enabled(dev_priv);
- else
- assert_pll_enabled(dev_priv, pipe);
+ assert_pll_enabled(dev_priv, pipe);
else {
if (pch_port) {
/* if driving the PCH, we need FDI enabled */
@@ -1797,7 +1728,6 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
* or we might hang the display.
*/
assert_planes_disabled(dev_priv, pipe);
- assert_cursor_disabled(dev_priv, pipe);
assert_sprites_disabled(dev_priv, pipe);
/* Don't disable pipe A or pipe A PLLs if needed */
@@ -1817,75 +1747,63 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
* Plane regs are double buffered, going from enabled->disabled needs a
* trigger in order to latch. The display address reg provides this.
*/
-void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
- enum plane plane)
+void intel_flush_display_plane(struct drm_i915_private *dev_priv,
+ enum plane plane)
{
- u32 reg = dev_priv->info->gen >= 4 ? DSPSURF(plane) : DSPADDR(plane);
-
- I915_WRITE(reg, I915_READ(reg));
- POSTING_READ(reg);
+ if (dev_priv->info->gen >= 4)
+ I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane)));
+ else
+ I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane)));
}
/**
- * intel_enable_primary_plane - enable the primary plane on a given pipe
+ * intel_enable_plane - enable a display plane on a given pipe
* @dev_priv: i915 private structure
* @plane: plane to enable
* @pipe: pipe being fed
*
* Enable @plane on @pipe, making sure that @pipe is running first.
*/
-static void intel_enable_primary_plane(struct drm_i915_private *dev_priv,
- enum plane plane, enum pipe pipe)
+static void intel_enable_plane(struct drm_i915_private *dev_priv,
+ enum plane plane, enum pipe pipe)
{
- struct intel_crtc *intel_crtc =
- to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
int reg;
u32 val;
/* If the pipe isn't enabled, we can't pump pixels and may hang */
assert_pipe_enabled(dev_priv, pipe);
- WARN(intel_crtc->primary_enabled, "Primary plane already enabled\n");
-
- intel_crtc->primary_enabled = true;
-
reg = DSPCNTR(plane);
val = I915_READ(reg);
if (val & DISPLAY_PLANE_ENABLE)
return;
I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE);
- intel_flush_primary_plane(dev_priv, plane);
+ intel_flush_display_plane(dev_priv, plane);
intel_wait_for_vblank(dev_priv->dev, pipe);
}
/**
- * intel_disable_primary_plane - disable the primary plane
+ * intel_disable_plane - disable a display plane
* @dev_priv: i915 private structure
* @plane: plane to disable
* @pipe: pipe consuming the data
*
* Disable @plane; should be an independent operation.
*/
-static void intel_disable_primary_plane(struct drm_i915_private *dev_priv,
- enum plane plane, enum pipe pipe)
+static void intel_disable_plane(struct drm_i915_private *dev_priv,
+ enum plane plane, enum pipe pipe)
{
- struct intel_crtc *intel_crtc =
- to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
int reg;
u32 val;
- WARN(!intel_crtc->primary_enabled, "Primary plane already disabled\n");
-
- intel_crtc->primary_enabled = false;
-
reg = DSPCNTR(plane);
val = I915_READ(reg);
if ((val & DISPLAY_PLANE_ENABLE) == 0)
return;
I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE);
- intel_flush_primary_plane(dev_priv, plane);
+ intel_flush_display_plane(dev_priv, plane);
intel_wait_for_vblank(dev_priv->dev, pipe);
}
@@ -1921,7 +1839,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
alignment = 0;
break;
case I915_TILING_Y:
- WARN(1, "Y tiled bo slipped through, driver bug!\n");
+ /* Despite that we check this in framebuffer_init userspace can
+ * screw us over and change the tiling after the fact. Only
+ * pinned buffers can't change their tiling. */
+ DRM_DEBUG_DRIVER("Y tiled not allowed for scan out buffers\n");
return -EINVAL;
default:
BUG();
@@ -2156,7 +2077,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
else
dspcntr &= ~DISPPLANE_TILED;
- if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+ if (IS_HASWELL(dev))
dspcntr &= ~DISPPLANE_TRICKLE_FEED_DISABLE;
else
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
@@ -2176,7 +2097,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
I915_MODIFY_DISPBASE(DSPSURF(plane),
i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
- if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ if (IS_HASWELL(dev)) {
I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
} else {
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
@@ -2323,26 +2244,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return ret;
}
- /*
- * Update pipe size and adjust fitter if needed: the reason for this is
- * that in compute_mode_changes we check the native mode (not the pfit
- * mode) to see if we can flip rather than do a full mode set. In the
- * fastboot case, we'll flip, but if we don't update the pipesrc and
- * pfit state, we'll end up with a big fb scanned out into the wrong
- * sized surface.
- *
- * To fix this properly, we need to hoist the checks up into
- * compute_mode_changes (or above), check the actual pfit state and
- * whether the platform allows pfit disable with pipe active, and only
- * then update the pipesrc and pfit state, even on the flip path.
- */
+ /* Update pipe size and adjust fitter if needed */
if (i915_fastboot) {
- const struct drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
-
I915_WRITE(PIPESRC(intel_crtc->pipe),
- ((adjusted_mode->crtc_hdisplay - 1) << 16) |
- (adjusted_mode->crtc_vdisplay - 1));
+ ((crtc->mode.hdisplay - 1) << 16) |
+ (crtc->mode.vdisplay - 1));
if (!intel_crtc->config.pch_pfit.enabled &&
(intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
@@ -2967,7 +2873,6 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
u32 divsel, phaseinc, auxdiv, phasedir = 0;
u32 temp;
@@ -2985,14 +2890,14 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
SBI_ICLK);
/* 20MHz is a corner case which is out of range for the 7-bit divisor */
- if (clock == 20000) {
+ if (crtc->mode.clock == 20000) {
auxdiv = 1;
divsel = 0x41;
phaseinc = 0x20;
} else {
/* The iCLK virtual clock root frequency is in MHz,
- * but the adjusted_mode->crtc_clock in in KHz. To get the
- * divisors, it is necessary to divide one by another, so we
+ * but the crtc->mode.clock in in KHz. To get the divisors,
+ * it is necessary to divide one by another, so we
* convert the virtual clock precision to KHz here for higher
* precision.
*/
@@ -3000,7 +2905,7 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
u32 iclk_pi_range = 64;
u32 desired_divisor, msb_divisor_value, pi_value;
- desired_divisor = (iclk_virtual_root_freq / clock);
+ desired_divisor = (iclk_virtual_root_freq / crtc->mode.clock);
msb_divisor_value = desired_divisor / iclk_pi_range;
pi_value = desired_divisor % iclk_pi_range;
@@ -3016,7 +2921,7 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
~SBI_SSCDIVINTPHASE_INCVAL_MASK);
DRM_DEBUG_KMS("iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n",
- clock,
+ crtc->mode.clock,
auxdiv,
divsel,
phasedir,
@@ -3381,108 +3286,6 @@ static void intel_disable_planes(struct drm_crtc *crtc)
intel_plane_disable(&intel_plane->base);
}
-void hsw_enable_ips(struct intel_crtc *crtc)
-{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-
- if (!crtc->config.ips_enabled)
- return;
-
- /* We can only enable IPS after we enable a plane and wait for a vblank.
- * We guarantee that the plane is enabled by calling intel_enable_ips
- * only after intel_enable_plane. And intel_enable_plane already waits
- * for a vblank, so all we need to do here is to enable the IPS bit. */
- assert_plane_enabled(dev_priv, crtc->plane);
- if (IS_BROADWELL(crtc->base.dev)) {
- mutex_lock(&dev_priv->rps.hw_lock);
- WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0xc0000000));
- mutex_unlock(&dev_priv->rps.hw_lock);
- /* Quoting Art Runyan: "its not safe to expect any particular
- * value in IPS_CTL bit 31 after enabling IPS through the
- * mailbox." Therefore we need to defer waiting on the state
- * change.
- * TODO: need to fix this for state checker
- */
- } else {
- I915_WRITE(IPS_CTL, IPS_ENABLE);
- /* The bit only becomes 1 in the next vblank, so this wait here
- * is essentially intel_wait_for_vblank. If we don't have this
- * and don't wait for vblanks until the end of crtc_enable, then
- * the HW state readout code will complain that the expected
- * IPS_CTL value is not the one we read. */
- if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50))
- DRM_ERROR("Timed out waiting for IPS enable\n");
- }
-}
-
-void hsw_disable_ips(struct intel_crtc *crtc)
-{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (!crtc->config.ips_enabled)
- return;
-
- assert_plane_enabled(dev_priv, crtc->plane);
- if (IS_BROADWELL(crtc->base.dev)) {
- mutex_lock(&dev_priv->rps.hw_lock);
- WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
- mutex_unlock(&dev_priv->rps.hw_lock);
- } else
- I915_WRITE(IPS_CTL, 0);
- POSTING_READ(IPS_CTL);
-
- /* We need to wait for a vblank before we can disable the plane. */
- intel_wait_for_vblank(dev, crtc->pipe);
-}
-
-/** Loads the palette/gamma unit for the CRTC with the prepared values */
-static void intel_crtc_load_lut(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
- int palreg = PALETTE(pipe);
- int i;
- bool reenable_ips = false;
-
- /* The clocks have to be on to load the palette. */
- if (!crtc->enabled || !intel_crtc->active)
- return;
-
- if (!HAS_PCH_SPLIT(dev_priv->dev)) {
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI))
- assert_dsi_pll_enabled(dev_priv);
- else
- assert_pll_enabled(dev_priv, pipe);
- }
-
- /* use legacy palette for Ironlake */
- if (HAS_PCH_SPLIT(dev))
- palreg = LGC_PALETTE(pipe);
-
- /* Workaround : Do not read or write the pipe palette/gamma data while
- * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
- */
- if (intel_crtc->config.ips_enabled &&
- ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
- GAMMA_MODE_MODE_SPLIT)) {
- hsw_disable_ips(intel_crtc);
- reenable_ips = true;
- }
-
- for (i = 0; i < 256; i++) {
- I915_WRITE(palreg + 4 * i,
- (intel_crtc->lut_r[i] << 16) |
- (intel_crtc->lut_g[i] << 8) |
- intel_crtc->lut_b[i]);
- }
-
- if (reenable_ips)
- hsw_enable_ips(intel_crtc);
-}
-
static void ironlake_crtc_enable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -3502,6 +3305,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
intel_set_pch_fifo_underrun_reporting(dev, pipe, true);
+ intel_update_watermarks(dev);
+
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_enable)
encoder->pre_enable(encoder);
@@ -3524,10 +3329,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
*/
intel_crtc_load_lut(crtc);
- intel_update_watermarks(crtc);
intel_enable_pipe(dev_priv, pipe,
- intel_crtc->config.has_pch_encoder, false);
- intel_enable_primary_plane(dev_priv, plane, pipe);
+ intel_crtc->config.has_pch_encoder);
+ intel_enable_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc);
intel_crtc_update_cursor(crtc, true);
@@ -3561,74 +3365,34 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
}
-static void haswell_crtc_enable_planes(struct drm_crtc *crtc)
+static void hsw_enable_ips(struct intel_crtc *crtc)
{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc->pipe;
- int plane = intel_crtc->plane;
-
- intel_enable_primary_plane(dev_priv, plane, pipe);
- intel_enable_planes(crtc);
- intel_crtc_update_cursor(crtc, true);
-
- hsw_enable_ips(intel_crtc);
-
- mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
- mutex_unlock(&dev->struct_mutex);
-}
-
-static void haswell_crtc_disable_planes(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc->pipe;
- int plane = intel_crtc->plane;
-
- intel_crtc_wait_for_pending_flips(crtc);
- drm_vblank_off(dev, pipe);
-
- /* FBC must be disabled before disabling the plane on HSW. */
- if (dev_priv->fbc.plane == plane)
- intel_disable_fbc(dev);
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
- hsw_disable_ips(intel_crtc);
+ if (!crtc->config.ips_enabled)
+ return;
- intel_crtc_update_cursor(crtc, false);
- intel_disable_planes(crtc);
- intel_disable_primary_plane(dev_priv, plane, pipe);
+ /* We can only enable IPS after we enable a plane and wait for a vblank.
+ * We guarantee that the plane is enabled by calling intel_enable_ips
+ * only after intel_enable_plane. And intel_enable_plane already waits
+ * for a vblank, so all we need to do here is to enable the IPS bit. */
+ assert_plane_enabled(dev_priv, crtc->plane);
+ I915_WRITE(IPS_CTL, IPS_ENABLE);
}
-/*
- * This implements the workaround described in the "notes" section of the mode
- * set sequence documentation. When going from no pipes or single pipe to
- * multiple pipes, and planes are enabled after the pipe, we need to wait at
- * least 2 vblanks on the first pipe before enabling planes on the second pipe.
- */
-static void haswell_mode_set_planes_workaround(struct intel_crtc *crtc)
+static void hsw_disable_ips(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
- struct intel_crtc *crtc_it, *other_active_crtc = NULL;
-
- /* We want to get the other_active_crtc only if there's only 1 other
- * active crtc. */
- list_for_each_entry(crtc_it, &dev->mode_config.crtc_list, base.head) {
- if (!crtc_it->active || crtc_it == crtc)
- continue;
-
- if (other_active_crtc)
- return;
+ struct drm_i915_private *dev_priv = dev->dev_private;
- other_active_crtc = crtc_it;
- }
- if (!other_active_crtc)
+ if (!crtc->config.ips_enabled)
return;
- intel_wait_for_vblank(dev, other_active_crtc->pipe);
- intel_wait_for_vblank(dev, other_active_crtc->pipe);
+ assert_plane_enabled(dev_priv, crtc->plane);
+ I915_WRITE(IPS_CTL, 0);
+
+ /* We need to wait for a vblank before we can disable the plane. */
+ intel_wait_for_vblank(dev, crtc->pipe);
}
static void haswell_crtc_enable(struct drm_crtc *crtc)
@@ -3638,6 +3402,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
+ int plane = intel_crtc->plane;
WARN_ON(!crtc->enabled);
@@ -3650,6 +3415,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
if (intel_crtc->config.has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
+ intel_update_watermarks(dev);
+
if (intel_crtc->config.has_pch_encoder)
dev_priv->display.fdi_link_train(crtc);
@@ -3670,22 +3437,23 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_ddi_set_pipe_settings(crtc);
intel_ddi_enable_transcoder_func(crtc);
- intel_update_watermarks(crtc);
intel_enable_pipe(dev_priv, pipe,
- intel_crtc->config.has_pch_encoder, false);
+ intel_crtc->config.has_pch_encoder);
+ intel_enable_plane(dev_priv, plane, pipe);
+ intel_enable_planes(crtc);
+ intel_crtc_update_cursor(crtc, true);
+
+ hsw_enable_ips(intel_crtc);
if (intel_crtc->config.has_pch_encoder)
lpt_pch_enable(crtc);
- for_each_encoder_on_crtc(dev, crtc, encoder) {
- encoder->enable(encoder);
- intel_opregion_notify_encoder(encoder, true);
- }
+ mutex_lock(&dev->struct_mutex);
+ intel_update_fbc(dev);
+ mutex_unlock(&dev->struct_mutex);
- /* If we change the relative order between pipe/planes enabling, we need
- * to change the workaround. */
- haswell_mode_set_planes_workaround(intel_crtc);
- haswell_crtc_enable_planes(crtc);
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->enable(encoder);
/*
* There seems to be a race in PCH platform hw (at least on some
@@ -3738,7 +3506,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
intel_crtc_update_cursor(crtc, false);
intel_disable_planes(crtc);
- intel_disable_primary_plane(dev_priv, plane, pipe);
+ intel_disable_plane(dev_priv, plane, pipe);
if (intel_crtc->config.has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev, pipe, false);
@@ -3779,7 +3547,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
}
intel_crtc->active = false;
- intel_update_watermarks(crtc);
+ intel_update_watermarks(dev);
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
@@ -3793,17 +3561,27 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
+ int plane = intel_crtc->plane;
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
if (!intel_crtc->active)
return;
- haswell_crtc_disable_planes(crtc);
-
- for_each_encoder_on_crtc(dev, crtc, encoder) {
- intel_opregion_notify_encoder(encoder, false);
+ for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder);
- }
+
+ intel_crtc_wait_for_pending_flips(crtc);
+ drm_vblank_off(dev, pipe);
+
+ /* FBC must be disabled before disabling the plane on HSW. */
+ if (dev_priv->fbc.plane == plane)
+ intel_disable_fbc(dev);
+
+ hsw_disable_ips(intel_crtc);
+
+ intel_crtc_update_cursor(crtc, false);
+ intel_disable_planes(crtc);
+ intel_disable_plane(dev_priv, plane, pipe);
if (intel_crtc->config.has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false);
@@ -3826,7 +3604,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
}
intel_crtc->active = false;
- intel_update_watermarks(crtc);
+ intel_update_watermarks(dev);
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
@@ -3918,7 +3696,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
- bool is_dsi;
WARN_ON(!crtc->enabled);
@@ -3926,15 +3703,13 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
return;
intel_crtc->active = true;
+ intel_update_watermarks(dev);
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);
- is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI);
-
- if (!is_dsi)
- vlv_enable_pll(intel_crtc);
+ vlv_enable_pll(intel_crtc);
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_enable)
@@ -3944,9 +3719,8 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
intel_crtc_load_lut(crtc);
- intel_update_watermarks(crtc);
- intel_enable_pipe(dev_priv, pipe, false, is_dsi);
- intel_enable_primary_plane(dev_priv, plane, pipe);
+ intel_enable_pipe(dev_priv, pipe, false);
+ intel_enable_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc);
intel_crtc_update_cursor(crtc, true);
@@ -3971,6 +3745,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
return;
intel_crtc->active = true;
+ intel_update_watermarks(dev);
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_enable)
@@ -3982,9 +3757,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
intel_crtc_load_lut(crtc);
- intel_update_watermarks(crtc);
- intel_enable_pipe(dev_priv, pipe, false, false);
- intel_enable_primary_plane(dev_priv, plane, pipe);
+ intel_enable_pipe(dev_priv, pipe, false);
+ intel_enable_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc);
/* The fixup needs to happen before cursor is enabled */
if (IS_G4X(dev))
@@ -4040,7 +3814,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
intel_crtc_dpms_overlay(intel_crtc, false);
intel_crtc_update_cursor(crtc, false);
intel_disable_planes(crtc);
- intel_disable_primary_plane(dev_priv, plane, pipe);
+ intel_disable_plane(dev_priv, plane, pipe);
intel_disable_pipe(dev_priv, pipe);
@@ -4050,15 +3824,11 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
if (encoder->post_disable)
encoder->post_disable(encoder);
- if (IS_VALLEYVIEW(dev) && !intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI))
- vlv_disable_pll(dev_priv, pipe);
- else if (!IS_VALLEYVIEW(dev))
- i9xx_disable_pll(dev_priv, pipe);
+ i9xx_disable_pll(dev_priv, pipe);
intel_crtc->active = false;
- intel_update_watermarks(crtc);
-
intel_update_fbc(dev);
+ intel_update_watermarks(dev);
}
static void i9xx_crtc_off(struct drm_crtc *crtc)
@@ -4132,7 +3902,6 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
dev_priv->display.off(crtc);
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
- assert_cursor_disabled(dev_priv, to_intel_crtc(crtc)->pipe);
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
if (crtc->fb) {
@@ -4260,7 +4029,7 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
return false;
}
- if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ if (IS_HASWELL(dev)) {
if (pipe_config->fdi_lanes > 2) {
DRM_DEBUG_KMS("only 2 lanes on haswell, required: %i lanes\n",
pipe_config->fdi_lanes);
@@ -4322,7 +4091,8 @@ retry:
*/
link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
- fdi_dotclock = adjusted_mode->crtc_clock;
+ fdi_dotclock = adjusted_mode->clock;
+ fdi_dotclock /= pipe_config->pixel_multiplier;
lane = ironlake_get_lanes_required(fdi_dotclock, link_bw,
pipe_config->pipe_bpp);
@@ -4364,39 +4134,13 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
struct drm_device *dev = crtc->base.dev;
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
- /* FIXME should check pixel clock limits on all platforms */
- if (INTEL_INFO(dev)->gen < 4) {
- struct drm_i915_private *dev_priv = dev->dev_private;
- int clock_limit =
- dev_priv->display.get_display_clock_speed(dev);
-
- /*
- * Enable pixel doubling when the dot clock
- * is > 90% of the (display) core speed.
- *
- * GDG double wide on either pipe,
- * otherwise pipe A only.
- */
- if ((crtc->pipe == PIPE_A || IS_I915G(dev)) &&
- adjusted_mode->crtc_clock > clock_limit * 9 / 10) {
- clock_limit *= 2;
- pipe_config->double_wide = true;
- }
-
- if (adjusted_mode->crtc_clock > clock_limit * 9 / 10)
+ if (HAS_PCH_SPLIT(dev)) {
+ /* FDI link clock is fixed at 2.7G */
+ if (pipe_config->requested_mode.clock * 3
+ > IRONLAKE_FDI_FREQ * 4)
return -EINVAL;
}
- /*
- * Pipe horizontal size must be even in:
- * - DVO ganged mode
- * - LVDS dual channel mode
- * - Double wide pipe
- */
- if ((intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
- intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
- pipe_config->pipe_src_w &= ~1;
-
/* Cantiga+ cannot handle modes with a hsync front porch of 0.
* WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
*/
@@ -4560,6 +4304,28 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
}
+static int vlv_get_refclk(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int refclk = 27000; /* for DP & HDMI */
+
+ return 100000; /* only one validated so far */
+
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
+ refclk = 96000;
+ } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+ if (intel_panel_use_ssc(dev_priv))
+ refclk = 100000;
+ else
+ refclk = 96000;
+ } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
+ refclk = 100000;
+ }
+
+ return refclk;
+}
+
static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
{
struct drm_device *dev = crtc->dev;
@@ -4567,7 +4333,7 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
int refclk;
if (IS_VALLEYVIEW(dev)) {
- refclk = 100000;
+ refclk = vlv_get_refclk(crtc);
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
refclk = dev_priv->vbt.lvds_ssc_freq * 1000;
@@ -4625,8 +4391,7 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
}
}
-static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
- pipe)
+static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv)
{
u32 reg_val;
@@ -4634,24 +4399,24 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
* PLLB opamp always calibrates to max value of 0x3f, force enable it
* and set it to a reasonable value instead.
*/
- reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF(1));
+ reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1));
reg_val &= 0xffffff00;
reg_val |= 0x00000030;
- vlv_dpio_write(dev_priv, pipe, DPIO_IREF(1), reg_val);
+ vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val);
- reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_CALIBRATION);
+ reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION);
reg_val &= 0x8cffffff;
reg_val = 0x8c000000;
- vlv_dpio_write(dev_priv, pipe, DPIO_CALIBRATION, reg_val);
+ vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val);
- reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF(1));
+ reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1));
reg_val &= 0xffffff00;
- vlv_dpio_write(dev_priv, pipe, DPIO_IREF(1), reg_val);
+ vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val);
- reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_CALIBRATION);
+ reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION);
reg_val &= 0x00ffffff;
reg_val |= 0xb0000000;
- vlv_dpio_write(dev_priv, pipe, DPIO_CALIBRATION, reg_val);
+ vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val);
}
static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
@@ -4717,18 +4482,18 @@ static void vlv_update_pll(struct intel_crtc *crtc)
/* PLL B needs special handling */
if (pipe)
- vlv_pllb_recal_opamp(dev_priv, pipe);
+ vlv_pllb_recal_opamp(dev_priv);
/* Set up Tx target for periodic Rcomp update */
- vlv_dpio_write(dev_priv, pipe, DPIO_IREF_BCAST, 0x0100000f);
+ vlv_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f);
/* Disable target IRef on PLL */
- reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF_CTL(pipe));
+ reg_val = vlv_dpio_read(dev_priv, DPIO_IREF_CTL(pipe));
reg_val &= 0x00ffffff;
- vlv_dpio_write(dev_priv, pipe, DPIO_IREF_CTL(pipe), reg_val);
+ vlv_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val);
/* Disable fast lock */
- vlv_dpio_write(dev_priv, pipe, DPIO_FASTCLK_DISABLE, 0x610);
+ vlv_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610);
/* Set idtafcrecal before PLL is enabled */
mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
@@ -4742,55 +4507,55 @@ static void vlv_update_pll(struct intel_crtc *crtc)
* Note: don't use the DAC post divider as it seems unstable.
*/
mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
- vlv_dpio_write(dev_priv, pipe, DPIO_DIV(pipe), mdiv);
+ vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
mdiv |= DPIO_ENABLE_CALIBRATION;
- vlv_dpio_write(dev_priv, pipe, DPIO_DIV(pipe), mdiv);
+ vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
/* Set HBR and RBR LPF coefficients */
if (crtc->config.port_clock == 162000 ||
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) ||
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
- vlv_dpio_write(dev_priv, pipe, DPIO_LPF_COEFF(pipe),
+ vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
0x009f0003);
else
- vlv_dpio_write(dev_priv, pipe, DPIO_LPF_COEFF(pipe),
+ vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
0x00d0000f);
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) ||
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) {
/* Use SSC source */
if (!pipe)
- vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
0x0df40000);
else
- vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
0x0df70000);
} else { /* HDMI or VGA */
/* Use bend source */
if (!pipe)
- vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
0x0df70000);
else
- vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
+ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
0x0df40000);
}
- coreclk = vlv_dpio_read(dev_priv, pipe, DPIO_CORE_CLK(pipe));
+ coreclk = vlv_dpio_read(dev_priv, DPIO_CORE_CLK(pipe));
coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) ||
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP))
coreclk |= 0x01000000;
- vlv_dpio_write(dev_priv, pipe, DPIO_CORE_CLK(pipe), coreclk);
+ vlv_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk);
- vlv_dpio_write(dev_priv, pipe, DPIO_PLL_CML(pipe), 0x87871000);
+ vlv_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000);
/* Enable DPIO clock input */
dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
- /* We should never disable this, set it here for state tracking */
- if (pipe == PIPE_B)
+ if (pipe)
dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
dpll |= DPLL_VCO_ENABLE;
crtc->config.dpll_hw_state.dpll = dpll;
@@ -4928,6 +4693,7 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode;
+ struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
uint32_t vsyncshift, crtc_vtotal, crtc_vblank_end;
/* We need to be careful not to changed the adjusted mode, for otherwise
@@ -4980,8 +4746,7 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
* always be the user's requested size.
*/
I915_WRITE(PIPESRC(pipe),
- ((intel_crtc->config.pipe_src_w - 1) << 16) |
- (intel_crtc->config.pipe_src_h - 1));
+ ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
}
static void intel_get_pipe_timings(struct intel_crtc *crtc,
@@ -5019,11 +4784,8 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
}
tmp = I915_READ(PIPESRC(crtc->pipe));
- pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
- pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
-
- pipe_config->requested_mode.vdisplay = pipe_config->pipe_src_h;
- pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w;
+ pipe_config->requested_mode.vdisplay = (tmp & 0xffff) + 1;
+ pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1;
}
static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc,
@@ -5043,7 +4805,7 @@ static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc,
crtc->mode.flags = pipe_config->adjusted_mode.flags;
- crtc->mode.clock = pipe_config->adjusted_mode.crtc_clock;
+ crtc->mode.clock = pipe_config->adjusted_mode.clock;
crtc->mode.flags |= pipe_config->adjusted_mode.flags;
}
@@ -5059,8 +4821,17 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE)
pipeconf |= PIPECONF_ENABLE;
- if (intel_crtc->config.double_wide)
- pipeconf |= PIPECONF_DOUBLE_WIDE;
+ if (intel_crtc->pipe == 0 && INTEL_INFO(dev)->gen < 4) {
+ /* Enable pixel doubling when the dot clock is > 90% of the (display)
+ * core speed.
+ *
+ * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
+ * pipe == 0 check?
+ */
+ if (intel_crtc->config.requested_mode.clock >
+ dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
+ pipeconf |= PIPECONF_DOUBLE_WIDE;
+ }
/* only g4x and later have fancy bpc/dither controls */
if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
@@ -5114,13 +4885,14 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
int refclk, num_connectors = 0;
intel_clock_t clock, reduced_clock;
u32 dspcntr;
bool ok, has_reduced_clock = false;
- bool is_lvds = false, is_dsi = false;
+ bool is_lvds = false;
struct intel_encoder *encoder;
const intel_limit_t *limit;
int ret;
@@ -5130,49 +4902,42 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
case INTEL_OUTPUT_LVDS:
is_lvds = true;
break;
- case INTEL_OUTPUT_DSI:
- is_dsi = true;
- break;
}
num_connectors++;
}
- if (is_dsi)
- goto skip_dpll;
+ refclk = i9xx_get_refclk(crtc, num_connectors);
- if (!intel_crtc->config.clock_set) {
- refclk = i9xx_get_refclk(crtc, num_connectors);
+ /*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE. The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ */
+ limit = intel_limit(crtc, refclk);
+ ok = dev_priv->display.find_dpll(limit, crtc,
+ intel_crtc->config.port_clock,
+ refclk, NULL, &clock);
+ if (!ok && !intel_crtc->config.clock_set) {
+ DRM_ERROR("Couldn't find PLL settings for mode!\n");
+ return -EINVAL;
+ }
+ if (is_lvds && dev_priv->lvds_downclock_avail) {
/*
- * Returns a set of divisors for the desired target clock with
- * the given refclk, or FALSE. The returned values represent
- * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n +
- * 2) / p1 / p2.
- */
- limit = intel_limit(crtc, refclk);
- ok = dev_priv->display.find_dpll(limit, crtc,
- intel_crtc->config.port_clock,
- refclk, NULL, &clock);
- if (!ok) {
- DRM_ERROR("Couldn't find PLL settings for mode!\n");
- return -EINVAL;
- }
-
- if (is_lvds && dev_priv->lvds_downclock_avail) {
- /*
- * Ensure we match the reduced clock's P to the target
- * clock. If the clocks don't match, we can't switch
- * the display clock by using the FP0/FP1. In such case
- * we will disable the LVDS downclock feature.
- */
- has_reduced_clock =
- dev_priv->display.find_dpll(limit, crtc,
- dev_priv->lvds_downclock,
- refclk, &clock,
- &reduced_clock);
- }
- /* Compat-code for transition, will disappear. */
+ * Ensure we match the reduced clock's P to the target clock.
+ * If the clocks don't match, we can't switch the display clock
+ * by using the FP0/FP1. In such case we will disable the LVDS
+ * downclock feature.
+ */
+ has_reduced_clock =
+ dev_priv->display.find_dpll(limit, crtc,
+ dev_priv->lvds_downclock,
+ refclk, &clock,
+ &reduced_clock);
+ }
+ /* Compat-code for transition, will disappear. */
+ if (!intel_crtc->config.clock_set) {
intel_crtc->config.dpll.n = clock.n;
intel_crtc->config.dpll.m1 = clock.m1;
intel_crtc->config.dpll.m2 = clock.m2;
@@ -5180,19 +4945,17 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
intel_crtc->config.dpll.p2 = clock.p2;
}
- if (IS_GEN2(dev)) {
+ if (IS_GEN2(dev))
i8xx_update_pll(intel_crtc,
has_reduced_clock ? &reduced_clock : NULL,
num_connectors);
- } else if (IS_VALLEYVIEW(dev)) {
+ else if (IS_VALLEYVIEW(dev))
vlv_update_pll(intel_crtc);
- } else {
+ else
i9xx_update_pll(intel_crtc,
has_reduced_clock ? &reduced_clock : NULL,
num_connectors);
- }
-skip_dpll:
/* Set up the display plane register */
dspcntr = DISPPLANE_GAMMA_ENABLE;
@@ -5209,8 +4972,8 @@ skip_dpll:
* which should always be the user's requested size.
*/
I915_WRITE(DSPSIZE(plane),
- ((intel_crtc->config.pipe_src_h - 1) << 16) |
- (intel_crtc->config.pipe_src_w - 1));
+ ((mode->vdisplay - 1) << 16) |
+ (mode->hdisplay - 1));
I915_WRITE(DSPPOS(plane), 0);
i9xx_set_pipeconf(intel_crtc);
@@ -5220,6 +4983,8 @@ skip_dpll:
ret = intel_pipe_set_base(crtc, x, y, fb);
+ intel_update_watermarks(dev);
+
return ret;
}
@@ -5250,32 +5015,6 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc,
I915_READ(LVDS) & LVDS_BORDER_ENABLE;
}
-static void vlv_crtc_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
-{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int pipe = pipe_config->cpu_transcoder;
- intel_clock_t clock;
- u32 mdiv;
- int refclk = 100000;
-
- mutex_lock(&dev_priv->dpio_lock);
- mdiv = vlv_dpio_read(dev_priv, pipe, DPIO_DIV(pipe));
- mutex_unlock(&dev_priv->dpio_lock);
-
- clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
- clock.m2 = mdiv & DPIO_M2DIV_MASK;
- clock.n = (mdiv >> DPIO_N_SHIFT) & 0xf;
- clock.p1 = (mdiv >> DPIO_P1_SHIFT) & 7;
- clock.p2 = (mdiv >> DPIO_P2_SHIFT) & 0x1f;
-
- vlv_clock(refclk, &clock);
-
- /* clock.dot is the fast clock */
- pipe_config->port_clock = clock.dot / 5;
-}
-
static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config)
{
@@ -5306,9 +5045,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
}
}
- if (INTEL_INFO(dev)->gen < 4)
- pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
-
intel_get_pipe_timings(crtc, pipe_config);
i9xx_get_pfit_config(crtc, pipe_config);
@@ -5341,11 +5077,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
DPLL_PORTB_READY_MASK);
}
- if (IS_VALLEYVIEW(dev))
- vlv_crtc_clock_get(crtc, pipe_config);
- else
- i9xx_crtc_clock_get(crtc, pipe_config);
-
return true;
}
@@ -5815,7 +5546,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
uint16_t postoff = 0;
if (intel_crtc->config.limited_color_range)
- postoff = (16 * (1 << 12) / 255) & 0x1fff;
+ postoff = (16 * (1 << 13) / 255) & 0x1fff;
I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff);
@@ -5834,16 +5565,14 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
static void haswell_set_pipeconf(struct drm_crtc *crtc)
{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
uint32_t val;
val = 0;
- if (IS_HASWELL(dev) && intel_crtc->config.dither)
+ if (intel_crtc->config.dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
@@ -5856,33 +5585,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT);
POSTING_READ(GAMMA_MODE(intel_crtc->pipe));
-
- if (IS_BROADWELL(dev)) {
- val = 0;
-
- switch (intel_crtc->config.pipe_bpp) {
- case 18:
- val |= PIPEMISC_DITHER_6_BPC;
- break;
- case 24:
- val |= PIPEMISC_DITHER_8_BPC;
- break;
- case 30:
- val |= PIPEMISC_DITHER_10_BPC;
- break;
- case 36:
- val |= PIPEMISC_DITHER_12_BPC;
- break;
- default:
- /* Case prevented by pipe_config_set_bpp. */
- BUG();
- }
-
- if (intel_crtc->config.dither)
- val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
-
- I915_WRITE(PIPEMISC(pipe), val);
- }
}
static bool ironlake_compute_clocks(struct drm_crtc *crtc,
@@ -6117,6 +5819,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
else
intel_crtc->lowfreq_avail = false;
+ if (intel_crtc->config.has_pch_encoder) {
+ pll = intel_crtc_to_shared_dpll(intel_crtc);
+
+ }
+
intel_set_pipe_timings(intel_crtc);
if (intel_crtc->config.has_pch_encoder) {
@@ -6132,67 +5839,25 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
ret = intel_pipe_set_base(crtc, x, y, fb);
- return ret;
-}
-
-static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
- struct intel_link_m_n *m_n)
-{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe pipe = crtc->pipe;
+ intel_update_watermarks(dev);
- m_n->link_m = I915_READ(PCH_TRANS_LINK_M1(pipe));
- m_n->link_n = I915_READ(PCH_TRANS_LINK_N1(pipe));
- m_n->gmch_m = I915_READ(PCH_TRANS_DATA_M1(pipe))
- & ~TU_SIZE_MASK;
- m_n->gmch_n = I915_READ(PCH_TRANS_DATA_N1(pipe));
- m_n->tu = ((I915_READ(PCH_TRANS_DATA_M1(pipe))
- & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+ return ret;
}
-static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
- enum transcoder transcoder,
- struct intel_link_m_n *m_n)
+static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe pipe = crtc->pipe;
+ enum transcoder transcoder = pipe_config->cpu_transcoder;
- if (INTEL_INFO(dev)->gen >= 5) {
- m_n->link_m = I915_READ(PIPE_LINK_M1(transcoder));
- m_n->link_n = I915_READ(PIPE_LINK_N1(transcoder));
- m_n->gmch_m = I915_READ(PIPE_DATA_M1(transcoder))
- & ~TU_SIZE_MASK;
- m_n->gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
- m_n->tu = ((I915_READ(PIPE_DATA_M1(transcoder))
- & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
- } else {
- m_n->link_m = I915_READ(PIPE_LINK_M_G4X(pipe));
- m_n->link_n = I915_READ(PIPE_LINK_N_G4X(pipe));
- m_n->gmch_m = I915_READ(PIPE_DATA_M_G4X(pipe))
- & ~TU_SIZE_MASK;
- m_n->gmch_n = I915_READ(PIPE_DATA_N_G4X(pipe));
- m_n->tu = ((I915_READ(PIPE_DATA_M_G4X(pipe))
- & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
- }
-}
-
-void intel_dp_get_m_n(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
-{
- if (crtc->config.has_pch_encoder)
- intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
- else
- intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
- &pipe_config->dp_m_n);
-}
-
-static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
-{
- intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
- &pipe_config->fdi_m_n);
+ pipe_config->fdi_m_n.link_m = I915_READ(PIPE_LINK_M1(transcoder));
+ pipe_config->fdi_m_n.link_n = I915_READ(PIPE_LINK_N1(transcoder));
+ pipe_config->fdi_m_n.gmch_m = I915_READ(PIPE_DATA_M1(transcoder))
+ & ~TU_SIZE_MASK;
+ pipe_config->fdi_m_n.gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
+ pipe_config->fdi_m_n.tu = ((I915_READ(PIPE_DATA_M1(transcoder))
+ & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
}
static void ironlake_get_pfit_config(struct intel_crtc *crtc,
@@ -6281,8 +5946,6 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
pipe_config->pixel_multiplier =
((tmp & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK)
>> PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT) + 1;
-
- ironlake_pch_clock_get(crtc, pipe_config);
} else {
pipe_config->pixel_multiplier = 1;
}
@@ -6339,8 +6002,8 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
* register. Callers should take care of disabling all the display engine
* functions, doing the mode unset, fixing interrupts, etc.
*/
-static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
- bool switch_to_fclk, bool allow_power_down)
+void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
+ bool switch_to_fclk, bool allow_power_down)
{
uint32_t val;
@@ -6368,10 +6031,7 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
val = I915_READ(D_COMP);
val |= D_COMP_COMP_DISABLE;
- mutex_lock(&dev_priv->rps.hw_lock);
- if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val))
- DRM_ERROR("Failed to disable D_COMP\n");
- mutex_unlock(&dev_priv->rps.hw_lock);
+ I915_WRITE(D_COMP, val);
POSTING_READ(D_COMP);
ndelay(100);
@@ -6390,7 +6050,7 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
* Fully restores LCPLL, disallowing power down and switching back to LCPLL
* source.
*/
-static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
+void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
{
uint32_t val;
@@ -6402,7 +6062,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
/* Make sure we're not on PC8 state before disabling PC8, otherwise
* we'll hang the machine! */
- gen6_gt_force_wake_get(dev_priv);
+ dev_priv->uncore.funcs.force_wake_get(dev_priv);
if (val & LCPLL_POWER_DOWN_ALLOW) {
val &= ~LCPLL_POWER_DOWN_ALLOW;
@@ -6413,10 +6073,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
val = I915_READ(D_COMP);
val |= D_COMP_COMP_FORCE;
val &= ~D_COMP_COMP_DISABLE;
- mutex_lock(&dev_priv->rps.hw_lock);
- if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val))
- DRM_ERROR("Failed to enable D_COMP\n");
- mutex_unlock(&dev_priv->rps.hw_lock);
+ I915_WRITE(D_COMP, val);
POSTING_READ(D_COMP);
val = I915_READ(LCPLL_CTL);
@@ -6436,7 +6093,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
DRM_ERROR("Switching back to LCPLL failed\n");
}
- gen6_gt_force_wake_put(dev_priv);
+ dev_priv->uncore.funcs.force_wake_put(dev_priv);
}
void hsw_enable_pc8_work(struct work_struct *__work)
@@ -6518,9 +6175,6 @@ static void __hsw_disable_package_c8(struct drm_i915_private *dev_priv)
void hsw_enable_package_c8(struct drm_i915_private *dev_priv)
{
- if (!HAS_PC8(dev_priv->dev))
- return;
-
mutex_lock(&dev_priv->pc8.lock);
__hsw_enable_package_c8(dev_priv);
mutex_unlock(&dev_priv->pc8.lock);
@@ -6528,9 +6182,6 @@ void hsw_enable_package_c8(struct drm_i915_private *dev_priv)
void hsw_disable_package_c8(struct drm_i915_private *dev_priv)
{
- if (!HAS_PC8(dev_priv->dev))
- return;
-
mutex_lock(&dev_priv->pc8.lock);
__hsw_disable_package_c8(dev_priv);
mutex_unlock(&dev_priv->pc8.lock);
@@ -6568,9 +6219,6 @@ static void hsw_update_package_c8(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
bool allow;
- if (!HAS_PC8(dev_priv->dev))
- return;
-
if (!i915_enable_pc8)
return;
@@ -6594,103 +6242,36 @@ done:
static void hsw_package_c8_gpu_idle(struct drm_i915_private *dev_priv)
{
- if (!HAS_PC8(dev_priv->dev))
- return;
-
- mutex_lock(&dev_priv->pc8.lock);
if (!dev_priv->pc8.gpu_idle) {
dev_priv->pc8.gpu_idle = true;
- __hsw_enable_package_c8(dev_priv);
+ hsw_enable_package_c8(dev_priv);
}
- mutex_unlock(&dev_priv->pc8.lock);
}
static void hsw_package_c8_gpu_busy(struct drm_i915_private *dev_priv)
{
- if (!HAS_PC8(dev_priv->dev))
- return;
-
- mutex_lock(&dev_priv->pc8.lock);
if (dev_priv->pc8.gpu_idle) {
dev_priv->pc8.gpu_idle = false;
- __hsw_disable_package_c8(dev_priv);
+ hsw_disable_package_c8(dev_priv);
}
- mutex_unlock(&dev_priv->pc8.lock);
-}
-
-#define for_each_power_domain(domain, mask) \
- for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
- if ((1 << (domain)) & (mask))
-
-static unsigned long get_pipe_power_domains(struct drm_device *dev,
- enum pipe pipe, bool pfit_enabled)
-{
- unsigned long mask;
- enum transcoder transcoder;
-
- transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
-
- mask = BIT(POWER_DOMAIN_PIPE(pipe));
- mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
- if (pfit_enabled)
- mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
-
- return mask;
}
-void intel_display_set_init_power(struct drm_device *dev, bool enable)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (dev_priv->power_domains.init_power_on == enable)
- return;
-
- if (enable)
- intel_display_power_get(dev, POWER_DOMAIN_INIT);
- else
- intel_display_power_put(dev, POWER_DOMAIN_INIT);
-
- dev_priv->power_domains.init_power_on = enable;
-}
-
-static void modeset_update_power_wells(struct drm_device *dev)
+static void haswell_modeset_global_resources(struct drm_device *dev)
{
- unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
+ bool enable = false;
struct intel_crtc *crtc;
- /*
- * First get all needed power domains, then put all unneeded, to avoid
- * any unnecessary toggling of the power wells.
- */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
- enum intel_display_power_domain domain;
-
if (!crtc->base.enabled)
continue;
- pipe_domains[crtc->pipe] = get_pipe_power_domains(dev,
- crtc->pipe,
- crtc->config.pch_pfit.enabled);
-
- for_each_power_domain(domain, pipe_domains[crtc->pipe])
- intel_display_power_get(dev, domain);
+ if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.enabled ||
+ crtc->config.cpu_transcoder != TRANSCODER_EDP)
+ enable = true;
}
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
- enum intel_display_power_domain domain;
+ intel_set_power_well(dev, enable);
- for_each_power_domain(domain, crtc->enabled_power_domains)
- intel_display_power_put(dev, domain);
-
- crtc->enabled_power_domains = pipe_domains[crtc->pipe];
- }
-
- intel_display_set_init_power(dev, false);
-}
-
-static void haswell_modeset_global_resources(struct drm_device *dev)
-{
- modeset_update_power_wells(dev);
hsw_update_package_c8(dev);
}
@@ -6729,6 +6310,8 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
ret = intel_pipe_set_base(crtc, x, y, fb);
+ intel_update_watermarks(dev);
+
return ret;
}
@@ -6836,44 +6419,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
return 0;
}
-static struct {
- int clock;
- u32 config;
-} hdmi_audio_clock[] = {
- { DIV_ROUND_UP(25200 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 },
- { 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */
- { 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 },
- { 27000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 },
- { 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 },
- { 54000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 },
- { DIV_ROUND_UP(74250 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 },
- { 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 },
- { DIV_ROUND_UP(148500 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 },
- { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 },
-};
-
-/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
-static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) {
- if (mode->clock == hdmi_audio_clock[i].clock)
- break;
- }
-
- if (i == ARRAY_SIZE(hdmi_audio_clock)) {
- DRM_DEBUG_KMS("HDMI audio pixel clock setting for %d not found, falling back to defaults\n", mode->clock);
- i = 1;
- }
-
- DRM_DEBUG_KMS("Configuring HDMI audio for pixel clock %d (0x%08x)\n",
- hdmi_audio_clock[i].clock,
- hdmi_audio_clock[i].config);
-
- return hdmi_audio_clock[i].config;
-}
-
static bool intel_eld_uptodate(struct drm_connector *connector,
int reg_eldv, uint32_t bits_eldv,
int reg_elda, uint32_t bits_elda,
@@ -6904,8 +6449,7 @@ static bool intel_eld_uptodate(struct drm_connector *connector,
}
static void g4x_write_eld(struct drm_connector *connector,
- struct drm_crtc *crtc,
- struct drm_display_mode *mode)
+ struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
uint8_t *eld = connector->eld;
@@ -6945,8 +6489,7 @@ static void g4x_write_eld(struct drm_connector *connector,
}
static void haswell_write_eld(struct drm_connector *connector,
- struct drm_crtc *crtc,
- struct drm_display_mode *mode)
+ struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
uint8_t *eld = connector->eld;
@@ -6999,9 +6542,8 @@ static void haswell_write_eld(struct drm_connector *connector,
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */
- } else {
- I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode));
- }
+ } else
+ I915_WRITE(aud_config, 0);
if (intel_eld_uptodate(connector,
aud_cntrl_st2, eldv,
@@ -7034,8 +6576,7 @@ static void haswell_write_eld(struct drm_connector *connector,
}
static void ironlake_write_eld(struct drm_connector *connector,
- struct drm_crtc *crtc,
- struct drm_display_mode *mode)
+ struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
uint8_t *eld = connector->eld;
@@ -7053,11 +6594,6 @@ static void ironlake_write_eld(struct drm_connector *connector,
aud_config = IBX_AUD_CFG(pipe);
aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
- } else if (IS_VALLEYVIEW(connector->dev)) {
- hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe);
- aud_config = VLV_AUD_CFG(pipe);
- aud_cntl_st = VLV_AUD_CNTL_ST(pipe);
- aud_cntrl_st2 = VLV_AUD_CNTL_ST2;
} else {
hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
aud_config = CPT_AUD_CFG(pipe);
@@ -7067,19 +6603,8 @@ static void ironlake_write_eld(struct drm_connector *connector,
DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));
- if (IS_VALLEYVIEW(connector->dev)) {
- struct intel_encoder *intel_encoder;
- struct intel_digital_port *intel_dig_port;
-
- intel_encoder = intel_attached_encoder(connector);
- intel_dig_port = enc_to_dig_port(&intel_encoder->base);
- i = intel_dig_port->port;
- } else {
- i = I915_READ(aud_cntl_st);
- i = (i >> 29) & DIP_PORT_SEL_MASK;
- /* DIP_Port_Select, 0x1 = PortB */
- }
-
+ i = I915_READ(aud_cntl_st);
+ i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */
if (!i) {
DRM_DEBUG_DRIVER("Audio directed to unknown port\n");
/* operate blindly on all ports */
@@ -7095,9 +6620,8 @@ static void ironlake_write_eld(struct drm_connector *connector,
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */
- } else {
- I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode));
- }
+ } else
+ I915_WRITE(aud_config, 0);
if (intel_eld_uptodate(connector,
aud_cntrl_st2, eldv,
@@ -7147,7 +6671,50 @@ void intel_write_eld(struct drm_encoder *encoder,
connector->eld[6] = drm_av_sync_delay(connector, mode) / 2;
if (dev_priv->display.write_eld)
- dev_priv->display.write_eld(connector, crtc, mode);
+ dev_priv->display.write_eld(connector, crtc);
+}
+
+/** Loads the palette/gamma unit for the CRTC with the prepared values */
+void intel_crtc_load_lut(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum pipe pipe = intel_crtc->pipe;
+ int palreg = PALETTE(pipe);
+ int i;
+ bool reenable_ips = false;
+
+ /* The clocks have to be on to load the palette. */
+ if (!crtc->enabled || !intel_crtc->active)
+ return;
+
+ if (!HAS_PCH_SPLIT(dev_priv->dev))
+ assert_pll_enabled(dev_priv, pipe);
+
+ /* use legacy palette for Ironlake */
+ if (HAS_PCH_SPLIT(dev))
+ palreg = LGC_PALETTE(pipe);
+
+ /* Workaround : Do not read or write the pipe palette/gamma data while
+ * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+ */
+ if (intel_crtc->config.ips_enabled &&
+ ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
+ GAMMA_MODE_MODE_SPLIT)) {
+ hsw_disable_ips(intel_crtc);
+ reenable_ips = true;
+ }
+
+ for (i = 0; i < 256; i++) {
+ I915_WRITE(palreg + 4 * i,
+ (intel_crtc->lut_r[i] << 16) |
+ (intel_crtc->lut_g[i] << 8) |
+ intel_crtc->lut_b[i]);
+ }
+
+ if (reenable_ips)
+ hsw_enable_ips(intel_crtc);
}
static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
@@ -7203,9 +6770,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
intel_crtc->cursor_visible = visible;
}
/* and commit changes on next vblank */
- POSTING_READ(CURCNTR(pipe));
I915_WRITE(CURBASE(pipe), base);
- POSTING_READ(CURBASE(pipe));
}
static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
@@ -7225,7 +6790,7 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
cntl |= CURSOR_MODE_DISABLE;
}
- if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ if (IS_HASWELL(dev)) {
cntl |= CURSOR_PIPE_CSC_ENABLE;
cntl &= ~CURSOR_TRICKLE_FEED_DISABLE;
}
@@ -7234,9 +6799,7 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
intel_crtc->cursor_visible = visible;
}
/* and commit changes on next vblank */
- POSTING_READ(CURCNTR_IVB(pipe));
I915_WRITE(CURBASE_IVB(pipe), base);
- POSTING_READ(CURBASE_IVB(pipe));
}
/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
@@ -7249,20 +6812,23 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
int pipe = intel_crtc->pipe;
int x = intel_crtc->cursor_x;
int y = intel_crtc->cursor_y;
- u32 base = 0, pos = 0;
+ u32 base, pos;
bool visible;
- if (on)
- base = intel_crtc->cursor_addr;
+ pos = 0;
- if (x >= intel_crtc->config.pipe_src_w)
- base = 0;
+ if (on && crtc->enabled && crtc->fb) {
+ base = intel_crtc->cursor_addr;
+ if (x > (int) crtc->fb->width)
+ base = 0;
- if (y >= intel_crtc->config.pipe_src_h)
+ if (y > (int) crtc->fb->height)
+ base = 0;
+ } else
base = 0;
if (x < 0) {
- if (x + intel_crtc->cursor_width <= 0)
+ if (x + intel_crtc->cursor_width < 0)
base = 0;
pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
@@ -7271,7 +6837,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
pos |= x << CURSOR_X_SHIFT;
if (y < 0) {
- if (y + intel_crtc->cursor_height <= 0)
+ if (y + intel_crtc->cursor_height < 0)
base = 0;
pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
@@ -7283,7 +6849,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
if (!visible && !intel_crtc->cursor_visible)
return;
- if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
I915_WRITE(CURPOS_IVB(pipe), pos);
ivb_update_cursor(crtc, base);
} else {
@@ -7414,8 +6980,8 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- intel_crtc->cursor_x = clamp_t(int, x, SHRT_MIN, SHRT_MAX);
- intel_crtc->cursor_y = clamp_t(int, y, SHRT_MIN, SHRT_MAX);
+ intel_crtc->cursor_x = x;
+ intel_crtc->cursor_y = y;
if (intel_crtc->active)
intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
@@ -7423,6 +6989,27 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
return 0;
}
+/** Sets the color ramps on behalf of RandR */
+void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+ u16 blue, int regno)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ intel_crtc->lut_r[regno] = red >> 8;
+ intel_crtc->lut_g[regno] = green >> 8;
+ intel_crtc->lut_b[regno] = blue >> 8;
+}
+
+void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ *red = intel_crtc->lut_r[regno] << 8;
+ *green = intel_crtc->lut_g[regno] << 8;
+ *blue = intel_crtc->lut_b[regno] << 8;
+}
+
static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t start, uint32_t size)
{
@@ -7458,21 +7045,14 @@ intel_framebuffer_create(struct drm_device *dev,
return ERR_PTR(-ENOMEM);
}
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- goto err;
-
ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
- mutex_unlock(&dev->struct_mutex);
- if (ret)
- goto err;
+ if (ret) {
+ drm_gem_object_unreference_unlocked(&obj->base);
+ kfree(intel_fb);
+ return ERR_PTR(ret);
+ }
return &intel_fb->base;
-err:
- drm_gem_object_unreference_unlocked(&obj->base);
- kfree(intel_fb);
-
- return ERR_PTR(ret);
}
static u32
@@ -7515,7 +7095,6 @@ static struct drm_framebuffer *
mode_fits_in_fbdev(struct drm_device *dev,
struct drm_display_mode *mode)
{
-#ifdef CONFIG_DRM_I915_FBDEV
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj;
struct drm_framebuffer *fb;
@@ -7536,9 +7115,6 @@ mode_fits_in_fbdev(struct drm_device *dev,
return NULL;
return fb;
-#else
- return NULL;
-#endif
}
bool intel_get_load_detect_pipe(struct drm_connector *connector,
@@ -7682,22 +7258,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
mutex_unlock(&crtc->mutex);
}
-static int i9xx_pll_refclk(struct drm_device *dev,
- const struct intel_crtc_config *pipe_config)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 dpll = pipe_config->dpll_hw_state.dpll;
-
- if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
- return dev_priv->vbt.lvds_ssc_freq * 1000;
- else if (HAS_PCH_SPLIT(dev))
- return 120000;
- else if (!IS_GEN2(dev))
- return 96000;
- else
- return 48000;
-}
-
/* Returns the clock of the currently programmed mode of the given pipe. */
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config)
@@ -7705,15 +7265,14 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = pipe_config->cpu_transcoder;
- u32 dpll = pipe_config->dpll_hw_state.dpll;
+ u32 dpll = I915_READ(DPLL(pipe));
u32 fp;
intel_clock_t clock;
- int refclk = i9xx_pll_refclk(dev, pipe_config);
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
- fp = pipe_config->dpll_hw_state.fp0;
+ fp = I915_READ(FP0(pipe));
else
- fp = pipe_config->dpll_hw_state.fp1;
+ fp = I915_READ(FP1(pipe));
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
if (IS_PINEVIEW(dev)) {
@@ -7744,13 +7303,14 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
default:
DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
"mode\n", (int)(dpll & DPLL_MODE_MASK));
+ pipe_config->adjusted_mode.clock = 0;
return;
}
if (IS_PINEVIEW(dev))
- pineview_clock(refclk, &clock);
+ pineview_clock(96000, &clock);
else
- i9xx_clock(refclk, &clock);
+ i9xx_clock(96000, &clock);
} else {
bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
@@ -7758,6 +7318,13 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
DPLL_FPA01_P1_POST_DIV_SHIFT);
clock.p2 = 14;
+
+ if ((dpll & PLL_REF_INPUT_MASK) ==
+ PLLB_REF_INPUT_SPREADSPECTRUMIN) {
+ /* XXX: might not be 66MHz */
+ i9xx_clock(66000, &clock);
+ } else
+ i9xx_clock(48000, &clock);
} else {
if (dpll & PLL_P1_DIVIDE_BY_TWO)
clock.p1 = 2;
@@ -7769,55 +7336,59 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
clock.p2 = 4;
else
clock.p2 = 2;
- }
- i9xx_clock(refclk, &clock);
+ i9xx_clock(48000, &clock);
+ }
}
- /*
- * This value includes pixel_multiplier. We will use
- * port_clock to compute adjusted_mode.crtc_clock in the
- * encoder's get_config() function.
- */
- pipe_config->port_clock = clock.dot;
+ pipe_config->adjusted_mode.clock = clock.dot;
}
-int intel_dotclock_calculate(int link_freq,
- const struct intel_link_m_n *m_n)
+static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config)
{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+ int link_freq, repeat;
+ u64 clock;
+ u32 link_m, link_n;
+
+ repeat = pipe_config->pixel_multiplier;
+
/*
* The calculation for the data clock is:
- * pixel_clock = ((m/n)*(link_clock * nr_lanes))/bpp
+ * pixel_clock = ((m/n)*(link_clock * nr_lanes * repeat))/bpp
* But we want to avoid losing precison if possible, so:
- * pixel_clock = ((m * link_clock * nr_lanes)/(n*bpp))
+ * pixel_clock = ((m * link_clock * nr_lanes * repeat)/(n*bpp))
*
* and the link clock is simpler:
- * link_clock = (m * link_clock) / n
+ * link_clock = (m * link_clock * repeat) / n
*/
- if (!m_n->link_n)
- return 0;
+ /*
+ * We need to get the FDI or DP link clock here to derive
+ * the M/N dividers.
+ *
+ * For FDI, we read it from the BIOS or use a fixed 2.7GHz.
+ * For DP, it's either 1.62GHz or 2.7GHz.
+ * We do our calculations in 10*MHz since we don't need much precison.
+ */
+ if (pipe_config->has_pch_encoder)
+ link_freq = intel_fdi_link_freq(dev) * 10000;
+ else
+ link_freq = pipe_config->port_clock;
- return div_u64((u64)m_n->link_m * link_freq, m_n->link_n);
-}
+ link_m = I915_READ(PIPE_LINK_M1(cpu_transcoder));
+ link_n = I915_READ(PIPE_LINK_N1(cpu_transcoder));
-static void ironlake_pch_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
-{
- struct drm_device *dev = crtc->base.dev;
+ if (!link_m || !link_n)
+ return;
- /* read out port_clock from the DPLL */
- i9xx_crtc_clock_get(crtc, pipe_config);
+ clock = ((u64)link_m * (u64)link_freq * (u64)repeat);
+ do_div(clock, link_n);
- /*
- * This value does not include pixel_multiplier.
- * We will check that port_clock and adjusted_mode.crtc_clock
- * agree once we know their relationship in the encoder's
- * get_config() function.
- */
- pipe_config->adjusted_mode.crtc_clock =
- intel_dotclock_calculate(intel_fdi_link_freq(dev) * 10000,
- &pipe_config->fdi_m_n);
+ pipe_config->adjusted_mode.clock = clock;
}
/** Returns the currently programmed mode of the given pipe. */
@@ -7833,7 +7404,6 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
int hsync = I915_READ(HSYNC(cpu_transcoder));
int vtot = I915_READ(VTOTAL(cpu_transcoder));
int vsync = I915_READ(VSYNC(cpu_transcoder));
- enum pipe pipe = intel_crtc->pipe;
mode = kzalloc(sizeof(*mode), GFP_KERNEL);
if (!mode)
@@ -7846,14 +7416,11 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
* Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
* to use a real value here instead.
*/
- pipe_config.cpu_transcoder = (enum transcoder) pipe;
+ pipe_config.cpu_transcoder = (enum transcoder) intel_crtc->pipe;
pipe_config.pixel_multiplier = 1;
- pipe_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe));
- pipe_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe));
- pipe_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe));
i9xx_crtc_clock_get(intel_crtc, &pipe_config);
- mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier;
+ mode->clock = pipe_config.adjusted_mode.clock;
mode->hdisplay = (htot & 0xffff) + 1;
mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
mode->hsync_start = (hsync & 0xffff) + 1;
@@ -7959,9 +7526,6 @@ void intel_mark_idle(struct drm_device *dev)
intel_decrease_pllclock(crtc);
}
-
- if (dev_priv->info->gen >= 6)
- gen6_rps_idle(dev->dev_private);
}
void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
@@ -8150,7 +7714,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, 0); /* aux display base address, unused */
intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
err_unpin:
@@ -8192,7 +7756,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, MI_NOOP);
intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
err_unpin:
@@ -8241,7 +7805,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, pf | pipesrc);
intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
err_unpin:
@@ -8286,7 +7850,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, pf | pipesrc);
intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
err_unpin:
@@ -8354,8 +7918,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
DERRMR_PIPEB_PRI_FLIP_DONE |
DERRMR_PIPEC_PRI_FLIP_DONE));
- intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1) |
- MI_SRM_LRM_GLOBAL_GTT);
+ intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1));
intel_ring_emit(ring, DERRMR);
intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
}
@@ -8366,7 +7929,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, (MI_NOOP));
intel_mark_page_flip_active(intel_crtc);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
err_unpin:
@@ -8411,7 +7974,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
fb->pitches[0] != crtc->fb->pitches[0]))
return -EINVAL;
- work = kzalloc(sizeof(*work), GFP_KERNEL);
+ work = kzalloc(sizeof *work, GFP_KERNEL);
if (work == NULL)
return -ENOMEM;
@@ -8646,17 +8209,6 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc,
return bpp;
}
-static void intel_dump_crtc_timings(const struct drm_display_mode *mode)
-{
- DRM_DEBUG_KMS("crtc timings: %d %d %d %d %d %d %d %d %d, "
- "type: 0x%x flags: 0x%x\n",
- mode->crtc_clock,
- mode->crtc_hdisplay, mode->crtc_hsync_start,
- mode->crtc_hsync_end, mode->crtc_htotal,
- mode->crtc_vdisplay, mode->crtc_vsync_start,
- mode->crtc_vsync_end, mode->crtc_vtotal, mode->type, mode->flags);
-}
-
static void intel_dump_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config,
const char *context)
@@ -8673,19 +8225,10 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
pipe_config->fdi_m_n.gmch_m, pipe_config->fdi_m_n.gmch_n,
pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n,
pipe_config->fdi_m_n.tu);
- DRM_DEBUG_KMS("dp: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
- pipe_config->has_dp_encoder,
- pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n,
- pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n,
- pipe_config->dp_m_n.tu);
DRM_DEBUG_KMS("requested mode:\n");
drm_mode_debug_printmodeline(&pipe_config->requested_mode);
DRM_DEBUG_KMS("adjusted mode:\n");
drm_mode_debug_printmodeline(&pipe_config->adjusted_mode);
- intel_dump_crtc_timings(&pipe_config->adjusted_mode);
- DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock);
- DRM_DEBUG_KMS("pipe src size: %dx%d\n",
- pipe_config->pipe_src_w, pipe_config->pipe_src_h);
DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n",
pipe_config->gmch_pfit.control,
pipe_config->gmch_pfit.pgm_ratios,
@@ -8695,7 +8238,6 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
pipe_config->pch_pfit.size,
pipe_config->pch_pfit.enabled ? "enabled" : "disabled");
DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
- DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
}
static bool check_encoder_cloning(struct drm_crtc *crtc)
@@ -8739,7 +8281,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
drm_mode_copy(&pipe_config->adjusted_mode, mode);
drm_mode_copy(&pipe_config->requested_mode, mode);
-
pipe_config->cpu_transcoder =
(enum transcoder) to_intel_crtc(crtc)->pipe;
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
@@ -8766,25 +8307,13 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
if (plane_bpp < 0)
goto fail;
- /*
- * Determine the real pipe dimensions. Note that stereo modes can
- * increase the actual pipe size due to the frame doubling and
- * insertion of additional space for blanks between the frame. This
- * is stored in the crtc timings. We use the requested mode to do this
- * computation to clearly distinguish it from the adjusted mode, which
- * can be changed by the connectors in the below retry loop.
- */
- drm_mode_set_crtcinfo(&pipe_config->requested_mode, CRTC_STEREO_DOUBLE);
- pipe_config->pipe_src_w = pipe_config->requested_mode.crtc_hdisplay;
- pipe_config->pipe_src_h = pipe_config->requested_mode.crtc_vdisplay;
-
encoder_retry:
/* Ensure the port clock defaults are reset when retrying. */
pipe_config->port_clock = 0;
pipe_config->pixel_multiplier = 1;
/* Fill in default crtc timings, allow encoders to overwrite them. */
- drm_mode_set_crtcinfo(&pipe_config->adjusted_mode, CRTC_STEREO_DOUBLE);
+ drm_mode_set_crtcinfo(&pipe_config->adjusted_mode, 0);
/* Pass our mode to the connectors and the CRTC to give them a chance to
* adjust it according to limitations or connector properties, and also
@@ -8805,8 +8334,7 @@ encoder_retry:
/* Set default port clock if not overwritten by the encoder. Needs to be
* done afterwards in case the encoder adjusts the mode. */
if (!pipe_config->port_clock)
- pipe_config->port_clock = pipe_config->adjusted_mode.crtc_clock
- * pipe_config->pixel_multiplier;
+ pipe_config->port_clock = pipe_config->adjusted_mode.clock;
ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
if (ret < 0) {
@@ -8993,9 +8521,13 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
}
-static bool intel_fuzzy_clock_check(int clock1, int clock2)
+static bool intel_fuzzy_clock_check(struct intel_crtc_config *cur,
+ struct intel_crtc_config *new)
{
- int diff;
+ int clock1, clock2, diff;
+
+ clock1 = cur->adjusted_mode.clock;
+ clock2 = new->adjusted_mode.clock;
if (clock1 == clock2)
return true;
@@ -9049,15 +8581,6 @@ intel_pipe_config_compare(struct drm_device *dev,
return false; \
}
-#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
- if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
- DRM_ERROR("mismatch in " #name " " \
- "(expected %i, found %i)\n", \
- current_config->name, \
- pipe_config->name); \
- return false; \
- }
-
#define PIPE_CONF_QUIRK(quirk) \
((current_config->quirks | pipe_config->quirks) & (quirk))
@@ -9071,13 +8594,6 @@ intel_pipe_config_compare(struct drm_device *dev,
PIPE_CONF_CHECK_I(fdi_m_n.link_n);
PIPE_CONF_CHECK_I(fdi_m_n.tu);
- PIPE_CONF_CHECK_I(has_dp_encoder);
- PIPE_CONF_CHECK_I(dp_m_n.gmch_m);
- PIPE_CONF_CHECK_I(dp_m_n.gmch_n);
- PIPE_CONF_CHECK_I(dp_m_n.link_m);
- PIPE_CONF_CHECK_I(dp_m_n.link_n);
- PIPE_CONF_CHECK_I(dp_m_n.tu);
-
PIPE_CONF_CHECK_I(adjusted_mode.crtc_hdisplay);
PIPE_CONF_CHECK_I(adjusted_mode.crtc_htotal);
PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_start);
@@ -9108,8 +8624,8 @@ intel_pipe_config_compare(struct drm_device *dev,
DRM_MODE_FLAG_NVSYNC);
}
- PIPE_CONF_CHECK_I(pipe_src_w);
- PIPE_CONF_CHECK_I(pipe_src_h);
+ PIPE_CONF_CHECK_I(requested_mode.hdisplay);
+ PIPE_CONF_CHECK_I(requested_mode.vdisplay);
PIPE_CONF_CHECK_I(gmch_pfit.control);
/* pfit ratios are autocomputed by the hw on gen4+ */
@@ -9124,8 +8640,6 @@ intel_pipe_config_compare(struct drm_device *dev,
PIPE_CONF_CHECK_I(ips_enabled);
- PIPE_CONF_CHECK_I(double_wide);
-
PIPE_CONF_CHECK_I(shared_dpll);
PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
@@ -9135,17 +8649,20 @@ intel_pipe_config_compare(struct drm_device *dev,
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
PIPE_CONF_CHECK_I(pipe_bpp);
- if (!IS_HASWELL(dev)) {
- PIPE_CONF_CHECK_CLOCK_FUZZY(adjusted_mode.crtc_clock);
- PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
- }
-
#undef PIPE_CONF_CHECK_X
#undef PIPE_CONF_CHECK_I
#undef PIPE_CONF_CHECK_FLAGS
-#undef PIPE_CONF_CHECK_CLOCK_FUZZY
#undef PIPE_CONF_QUIRK
+ if (!IS_HASWELL(dev)) {
+ if (!intel_fuzzy_clock_check(current_config, pipe_config)) {
+ DRM_ERROR("mismatch in clock (expected %d, found %d)\n",
+ current_config->adjusted_mode.clock,
+ pipe_config->adjusted_mode.clock);
+ return false;
+ }
+ }
+
return true;
}
@@ -9272,10 +8789,14 @@ check_crtc_state(struct drm_device *dev)
enum pipe pipe;
if (encoder->base.crtc != &crtc->base)
continue;
- if (encoder->get_hw_state(encoder, &pipe))
+ if (encoder->get_config &&
+ encoder->get_hw_state(encoder, &pipe))
encoder->get_config(encoder, &pipe_config);
}
+ if (dev_priv->display.get_clock)
+ dev_priv->display.get_clock(crtc, &pipe_config);
+
WARN(crtc->active != active,
"crtc active state doesn't match with hw state "
"(expected %i, found %i)\n", crtc->active, active);
@@ -9350,18 +8871,6 @@ intel_modeset_check_state(struct drm_device *dev)
check_shared_dpll_state(dev);
}
-void ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
- int dotclock)
-{
- /*
- * FDI already provided one idea for the dotclock.
- * Yell if the encoder disagrees.
- */
- WARN(!intel_fuzzy_clock_check(pipe_config->adjusted_mode.crtc_clock, dotclock),
- "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
- pipe_config->adjusted_mode.crtc_clock, dotclock);
-}
-
static int __intel_set_mode(struct drm_crtc *crtc,
struct drm_display_mode *mode,
int x, int y, struct drm_framebuffer *fb)
@@ -9374,7 +8883,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
unsigned disable_pipes, prepare_pipes, modeset_pipes;
int ret = 0;
- saved_mode = kcalloc(2, sizeof(*saved_mode), GFP_KERNEL);
+ saved_mode = kmalloc(2 * sizeof(*saved_mode), GFP_KERNEL);
if (!saved_mode)
return -ENOMEM;
saved_hwmode = saved_mode + 1;
@@ -9913,7 +9422,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
struct intel_crtc *intel_crtc;
int i;
- intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
+ intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
if (intel_crtc == NULL)
return;
@@ -9942,18 +9451,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
}
-enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
-{
- struct drm_encoder *encoder = connector->base.encoder;
-
- WARN_ON(!mutex_is_locked(&connector->base.dev->mode_config.mutex));
-
- if (!encoder)
- return INVALID_PIPE;
-
- return to_intel_crtc(encoder->crtc)->pipe;
-}
-
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -9969,7 +9466,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
if (!drmmode_obj) {
DRM_ERROR("no such CRTC id\n");
- return -ENOENT;
+ return -EINVAL;
}
crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
@@ -10050,7 +9547,7 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_ddi_init(dev, PORT_D);
} else if (HAS_PCH_SPLIT(dev)) {
int found;
- dpd_is_edp = intel_dp_is_edp(dev, PORT_D);
+ dpd_is_edp = intel_dpd_is_edp(dev);
if (has_edp_a(dev))
intel_dp_init(dev, DP_A, PORT_A);
@@ -10076,21 +9573,21 @@ static void intel_setup_outputs(struct drm_device *dev)
if (I915_READ(PCH_DP_D) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_D, PORT_D);
} else if (IS_VALLEYVIEW(dev)) {
- if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) {
- intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB,
- PORT_B);
- if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED)
- intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B);
- }
-
+ /* Check for built-in panel first. Shares lanes with HDMI on SDVOC */
if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) {
intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC,
PORT_C);
if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED)
- intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C);
+ intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C,
+ PORT_C);
}
- intel_dsi_init(dev);
+ if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) {
+ intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB,
+ PORT_B);
+ if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED)
+ intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B);
+ }
} else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
bool found = false;
@@ -10146,7 +9643,6 @@ static void intel_setup_outputs(struct drm_device *dev)
void intel_framebuffer_fini(struct intel_framebuffer *fb)
{
drm_framebuffer_cleanup(&fb->base);
- WARN_ON(!fb->obj->framebuffer_references--);
drm_gem_object_unreference_unlocked(&fb->obj->base);
}
@@ -10178,12 +9674,9 @@ int intel_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
- int aligned_height, tile_height;
int pitch_limit;
int ret;
- WARN_ON(!mutex_is_locked(&dev->struct_mutex));
-
if (obj->tiling_mode == I915_TILING_Y) {
DRM_DEBUG("hardware does not support tiling Y\n");
return -EINVAL;
@@ -10272,16 +9765,8 @@ int intel_framebuffer_init(struct drm_device *dev,
if (mode_cmd->offsets[0] != 0)
return -EINVAL;
- tile_height = IS_GEN2(dev) ? 16 : 8;
- aligned_height = ALIGN(mode_cmd->height,
- obj->tiling_mode ? tile_height : 1);
- /* FIXME drm helper for size checks (especially planar formats)? */
- if (obj->base.size < aligned_height * mode_cmd->pitches[0])
- return -EINVAL;
-
drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
intel_fb->obj = obj;
- intel_fb->obj->framebuffer_references++;
ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
if (ret) {
@@ -10307,15 +9792,9 @@ intel_user_framebuffer_create(struct drm_device *dev,
return intel_framebuffer_create(dev, mode_cmd, obj);
}
-#ifndef CONFIG_DRM_I915_FBDEV
-static inline void intel_fbdev_output_poll_changed(struct drm_device *dev)
-{
-}
-#endif
-
static const struct drm_mode_config_funcs intel_mode_funcs = {
.fb_create = intel_user_framebuffer_create,
- .output_poll_changed = intel_fbdev_output_poll_changed,
+ .output_poll_changed = intel_fb_output_poll_changed,
};
/* Set up chip specific display functions */
@@ -10341,6 +9820,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.update_plane = ironlake_update_plane;
} else if (HAS_PCH_SPLIT(dev)) {
dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
+ dev_priv->display.get_clock = ironlake_crtc_clock_get;
dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
dev_priv->display.crtc_enable = ironlake_crtc_enable;
dev_priv->display.crtc_disable = ironlake_crtc_disable;
@@ -10348,6 +9828,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.update_plane = ironlake_update_plane;
} else if (IS_VALLEYVIEW(dev)) {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+ dev_priv->display.get_clock = i9xx_crtc_clock_get;
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
dev_priv->display.crtc_enable = valleyview_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -10355,6 +9836,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.update_plane = i9xx_update_plane;
} else {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+ dev_priv->display.get_clock = i9xx_crtc_clock_get;
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -10404,7 +9886,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.write_eld = ironlake_write_eld;
dev_priv->display.modeset_global_resources =
ivb_modeset_global_resources;
- } else if (IS_HASWELL(dev) || IS_GEN8(dev)) {
+ } else if (IS_HASWELL(dev)) {
dev_priv->display.fdi_link_train = hsw_fdi_link_train;
dev_priv->display.write_eld = haswell_write_eld;
dev_priv->display.modeset_global_resources =
@@ -10412,8 +9894,7 @@ static void intel_init_display(struct drm_device *dev)
}
} else if (IS_G4X(dev)) {
dev_priv->display.write_eld = g4x_write_eld;
- } else if (IS_VALLEYVIEW(dev))
- dev_priv->display.write_eld = ironlake_write_eld;
+ }
/* Default just returns -ENODEV to indicate unsupported */
dev_priv->display.queue_flip = intel_default_queue_flip;
@@ -10436,7 +9917,6 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.queue_flip = intel_gen6_queue_flip;
break;
case 7:
- case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
dev_priv->display.queue_flip = intel_gen7_queue_flip;
break;
}
@@ -10532,7 +10012,8 @@ static struct intel_quirk intel_quirks[] = {
/* ThinkPad T60 needs pipe A force quirk (bug #16494) */
{ 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
- /* 830 needs to leave pipe A & dpll A up */
+ /* 830/845 need to leave pipe A & dpll A up */
+ { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
/* Lenovo U160 cannot use SSC on LVDS */
@@ -10541,11 +10022,20 @@ static struct intel_quirk intel_quirks[] = {
/* Sony Vaio Y cannot use SSC on LVDS */
{ 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
- /*
- * All GM45 Acer (and its brands eMachines and Packard Bell) laptops
- * seem to use inverted backlight PWM.
- */
- { 0x2a42, 0x1025, PCI_ANY_ID, quirk_invert_brightness },
+ /* Acer Aspire 5734Z must invert backlight brightness */
+ { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
+
+ /* Acer/eMachines G725 */
+ { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
+
+ /* Acer/eMachines e725 */
+ { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
+
+ /* Acer/Packard Bell NCL20 */
+ { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
+
+ /* Acer Aspire 4736Z */
+ { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
/* Dell XPS13 HD Sandy Bridge */
{ 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
@@ -10594,19 +10084,12 @@ static void i915_disable_vga(struct drm_device *dev)
void intel_modeset_init_hw(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
+ intel_init_power_well(dev);
intel_prepare_ddi(dev);
intel_init_clock_gating(dev);
- /* Enable the CRI clock source so we can get at the display */
- if (IS_VALLEYVIEW(dev))
- I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
- DPLL_INTEGRATED_CRI_CLK_VLV);
-
- intel_init_dpio(dev);
-
mutex_lock(&dev->struct_mutex);
intel_enable_gt_powersave(dev);
mutex_unlock(&dev->struct_mutex);
@@ -10874,7 +10357,7 @@ void i915_redisable_vga(struct drm_device *dev)
(I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE_ENABLED) == 0)
return;
- if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) {
+ if (I915_READ(vga_reg) != VGA_DISP_DISABLE) {
DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
i915_disable_vga(dev);
}
@@ -10897,7 +10380,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
&crtc->config);
crtc->base.enabled = crtc->active;
- crtc->primary_enabled = crtc->active;
DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
crtc->base.base.id,
@@ -10931,17 +10413,27 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
if (encoder->get_hw_state(encoder, &pipe)) {
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
encoder->base.crtc = &crtc->base;
- encoder->get_config(encoder, &crtc->config);
+ if (encoder->get_config)
+ encoder->get_config(encoder, &crtc->config);
} else {
encoder->base.crtc = NULL;
}
encoder->connectors_active = false;
- DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n",
encoder->base.base.id,
drm_get_encoder_name(&encoder->base),
encoder->base.crtc ? "enabled" : "disabled",
- pipe_name(pipe));
+ pipe);
+ }
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list,
+ base.head) {
+ if (!crtc->active)
+ continue;
+ if (dev_priv->display.get_clock)
+ dev_priv->display.get_clock(crtc,
+ &crtc->config);
}
list_for_each_entry(connector, &dev->mode_config.connector_list,
@@ -10968,6 +10460,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
{
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe;
+ struct drm_plane *plane;
struct intel_crtc *crtc;
struct intel_encoder *encoder;
int i;
@@ -11014,12 +10507,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
pll->on = false;
}
- if (IS_HASWELL(dev))
- ilk_wm_get_hw_state(dev);
-
if (force_restore) {
- i915_redisable_vga(dev);
-
/*
* We need to use raw interfaces for restoring state to avoid
* checking (bogus) intermediate states.
@@ -11031,6 +10519,10 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
__intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
crtc->fb);
}
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head)
+ intel_plane_restore(plane);
+
+ i915_redisable_vga(dev);
} else {
intel_modeset_update_staged_output_state(dev);
}
@@ -11053,7 +10545,6 @@ void intel_modeset_cleanup(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
- struct drm_connector *connector;
/*
* Interrupts and polling as the first thing to avoid creating havoc.
@@ -11094,10 +10585,6 @@ void intel_modeset_cleanup(struct drm_device *dev)
/* destroy backlight, if any, before the connectors */
intel_panel_destroy_backlight(dev);
- /* destroy the sysfs files before encoders/connectors */
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- drm_sysfs_connector_remove(connector);
-
drm_mode_config_cleanup(dev);
intel_cleanup_overlay(dev);
@@ -11193,7 +10680,7 @@ intel_display_capture_error_state(struct drm_device *dev)
if (INTEL_INFO(dev)->num_pipes == 0)
return NULL;
- error = kzalloc(sizeof(*error), GFP_ATOMIC);
+ error = kmalloc(sizeof(*error), GFP_ATOMIC);
if (error == NULL)
return NULL;
@@ -11201,9 +10688,6 @@ intel_display_capture_error_state(struct drm_device *dev)
error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
for_each_pipe(i) {
- if (!intel_display_power_enabled(dev, POWER_DOMAIN_PIPE(i)))
- continue;
-
if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) {
error->cursor[i].control = I915_READ(CURCNTR(i));
error->cursor[i].position = I915_READ(CURPOS(i));
@@ -11237,10 +10721,6 @@ intel_display_capture_error_state(struct drm_device *dev)
for (i = 0; i < error->num_transcoders; i++) {
enum transcoder cpu_transcoder = transcoders[i];
- if (!intel_display_power_enabled(dev,
- POWER_DOMAIN_TRANSCODER(cpu_transcoder)))
- continue;
-
error->transcoder[i].cpu_transcoder = cpu_transcoder;
error->transcoder[i].conf = I915_READ(PIPECONF(cpu_transcoder));
@@ -11252,6 +10732,12 @@ intel_display_capture_error_state(struct drm_device *dev)
error->transcoder[i].vsync = I915_READ(VSYNC(cpu_transcoder));
}
+ /* In the code above we read the registers without checking if the power
+ * well was on, so here we have to clear the FPGA_DBG_RM_NOCLAIM bit to
+ * prevent the next I915_WRITE from detecting it and printing an error
+ * message. */
+ intel_uncore_clear_errors(dev);
+
return error;
}
@@ -11296,7 +10782,7 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m,
}
for (i = 0; i < error->num_transcoders; i++) {
- err_printf(m, "CPU transcoder: %c\n",
+ err_printf(m, " CPU transcoder: %c\n",
transcoder_name(error->transcoder[i].cpu_transcoder));
err_printf(m, " CONF: %08x\n", error->transcoder[i].conf);
err_printf(m, " HTOTAL: %08x\n", error->transcoder[i].htotal);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 30c627c..1a43137 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -38,32 +38,6 @@
#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
-struct dp_link_dpll {
- int link_bw;
- struct dpll dpll;
-};
-
-static const struct dp_link_dpll gen4_dpll[] = {
- { DP_LINK_BW_1_62,
- { .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8 } },
- { DP_LINK_BW_2_7,
- { .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2 } }
-};
-
-static const struct dp_link_dpll pch_dpll[] = {
- { DP_LINK_BW_1_62,
- { .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9 } },
- { DP_LINK_BW_2_7,
- { .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8 } }
-};
-
-static const struct dp_link_dpll vlv_dpll[] = {
- { DP_LINK_BW_1_62,
- { .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81 } },
- { DP_LINK_BW_2_7,
- { .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27 } }
-};
-
/**
* is_edp - is the given port attached to an eDP panel (either CPU or PCH)
* @intel_dp: DP struct
@@ -237,77 +211,24 @@ intel_hrawclk(struct drm_device *dev)
}
}
-static void
-intel_dp_init_panel_power_sequencer(struct drm_device *dev,
- struct intel_dp *intel_dp,
- struct edp_power_seq *out);
-static void
-intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
- struct intel_dp *intel_dp,
- struct edp_power_seq *out);
-
-static enum pipe
-vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
-{
- struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
- struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
- struct drm_device *dev = intel_dig_port->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- enum port port = intel_dig_port->port;
- enum pipe pipe;
-
- /* modeset should have pipe */
- if (crtc)
- return to_intel_crtc(crtc)->pipe;
-
- /* init time, try to find a pipe with this port selected */
- for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
- u32 port_sel = I915_READ(VLV_PIPE_PP_ON_DELAYS(pipe)) &
- PANEL_PORT_SELECT_MASK;
- if (port_sel == PANEL_PORT_SELECT_DPB_VLV && port == PORT_B)
- return pipe;
- if (port_sel == PANEL_PORT_SELECT_DPC_VLV && port == PORT_C)
- return pipe;
- }
-
- /* shrug */
- return PIPE_A;
-}
-
-static u32 _pp_ctrl_reg(struct intel_dp *intel_dp)
-{
- struct drm_device *dev = intel_dp_to_dev(intel_dp);
-
- if (HAS_PCH_SPLIT(dev))
- return PCH_PP_CONTROL;
- else
- return VLV_PIPE_PP_CONTROL(vlv_power_sequencer_pipe(intel_dp));
-}
-
-static u32 _pp_stat_reg(struct intel_dp *intel_dp)
-{
- struct drm_device *dev = intel_dp_to_dev(intel_dp);
-
- if (HAS_PCH_SPLIT(dev))
- return PCH_PP_STATUS;
- else
- return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
-}
-
static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 pp_stat_reg;
- return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
+ pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+ return (I915_READ(pp_stat_reg) & PP_ON) != 0;
}
static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 pp_ctrl_reg;
- return (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0;
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+ return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0;
}
static void
@@ -315,15 +236,19 @@ intel_dp_check_edp(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 pp_stat_reg, pp_ctrl_reg;
if (!is_edp(intel_dp))
return;
+ pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+
if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) {
WARN(1, "eDP powered off while attempting aux channel communication.\n");
DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n",
- I915_READ(_pp_stat_reg(intel_dp)),
- I915_READ(_pp_ctrl_reg(intel_dp)));
+ I915_READ(pp_stat_reg),
+ I915_READ(pp_ctrl_reg));
}
}
@@ -405,7 +330,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
uint32_t status;
int try, precharge, clock = 0;
bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev);
- uint32_t timeout;
/* dp aux is extremely sensitive to irq latency, hence request the
* lowest possible wakeup latency and so prevent the cpu from going into
@@ -420,11 +344,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
else
precharge = 5;
- if (IS_BROADWELL(dev) && ch_ctl == DPA_AUX_CH_CTL)
- timeout = DP_AUX_CH_CTL_TIME_OUT_600us;
- else
- timeout = DP_AUX_CH_CTL_TIME_OUT_400us;
-
intel_aux_display_runtime_get(dev_priv);
/* Try to wait for any previous AUX channel activity */
@@ -442,12 +361,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
goto out;
}
- /* Only 5 data registers! */
- if (WARN_ON(send_bytes > 20 || recv_size > 20)) {
- ret = -E2BIG;
- goto out;
- }
-
while ((aux_clock_divider = get_aux_clock_divider(intel_dp, clock++))) {
/* Must try at least 3 times according to DP spec */
for (try = 0; try < 5; try++) {
@@ -460,7 +373,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
I915_WRITE(ch_ctl,
DP_AUX_CH_CTL_SEND_BUSY |
(has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) |
- timeout |
+ DP_AUX_CH_CTL_TIME_OUT_400us |
(send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
(precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
(aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
@@ -538,10 +451,9 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
int msg_bytes;
uint8_t ack;
- if (WARN_ON(send_bytes > 16))
- return -E2BIG;
-
intel_dp_check_edp(intel_dp);
+ if (send_bytes > 16)
+ return -1;
msg[0] = AUX_NATIVE_WRITE << 4;
msg[1] = address >> 8;
msg[2] = address & 0xff;
@@ -582,9 +494,6 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp,
uint8_t ack;
int ret;
- if (WARN_ON(recv_bytes > 19))
- return -E2BIG;
-
intel_dp_check_edp(intel_dp);
msg[0] = AUX_NATIVE_READ << 4;
msg[1] = address >> 8;
@@ -629,7 +538,6 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
int reply_bytes;
int ret;
- ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_check_edp(intel_dp);
/* Set up the command byte */
if (mode & MODE_I2C_READ)
@@ -661,18 +569,13 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
break;
}
- /*
- * DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device is
- * required to retry at least seven times upon receiving AUX_DEFER
- * before giving up the AUX transaction.
- */
- for (retry = 0; retry < 7; retry++) {
+ for (retry = 0; retry < 5; retry++) {
ret = intel_dp_aux_ch(intel_dp,
msg, msg_bytes,
reply, reply_bytes);
if (ret < 0) {
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
- goto out;
+ return ret;
}
switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
@@ -683,8 +586,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
break;
case AUX_NATIVE_REPLY_NACK:
DRM_DEBUG_KMS("aux_ch native nack\n");
- ret = -EREMOTEIO;
- goto out;
+ return -EREMOTEIO;
case AUX_NATIVE_REPLY_DEFER:
/*
* For now, just give more slack to branch devices. We
@@ -702,8 +604,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
default:
DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
reply[0]);
- ret = -EREMOTEIO;
- goto out;
+ return -EREMOTEIO;
}
switch (reply[0] & AUX_I2C_REPLY_MASK) {
@@ -711,29 +612,22 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
if (mode == MODE_I2C_READ) {
*read_byte = reply[1];
}
- ret = reply_bytes - 1;
- goto out;
+ return reply_bytes - 1;
case AUX_I2C_REPLY_NACK:
DRM_DEBUG_KMS("aux_i2c nack\n");
- ret = -EREMOTEIO;
- goto out;
+ return -EREMOTEIO;
case AUX_I2C_REPLY_DEFER:
DRM_DEBUG_KMS("aux_i2c defer\n");
udelay(100);
break;
default:
DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
- ret = -EREMOTEIO;
- goto out;
+ return -EREMOTEIO;
}
}
DRM_ERROR("too many retries, giving up\n");
- ret = -EREMOTEIO;
-
-out:
- ironlake_edp_panel_vdd_off(intel_dp, false);
- return ret;
+ return -EREMOTEIO;
}
static int
@@ -753,9 +647,11 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
intel_dp->adapter.algo_data = &intel_dp->algo;
- intel_dp->adapter.dev.parent = intel_connector->base.kdev;
+ intel_dp->adapter.dev.parent = &intel_connector->base.kdev;
+ ironlake_edp_panel_vdd_on(intel_dp);
ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
+ ironlake_edp_panel_vdd_off(intel_dp, false);
return ret;
}
@@ -764,30 +660,41 @@ intel_dp_set_clock(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config, int link_bw)
{
struct drm_device *dev = encoder->base.dev;
- const struct dp_link_dpll *divisor = NULL;
- int i, count = 0;
if (IS_G4X(dev)) {
- divisor = gen4_dpll;
- count = ARRAY_SIZE(gen4_dpll);
+ if (link_bw == DP_LINK_BW_1_62) {
+ pipe_config->dpll.p1 = 2;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.n = 2;
+ pipe_config->dpll.m1 = 23;
+ pipe_config->dpll.m2 = 8;
+ } else {
+ pipe_config->dpll.p1 = 1;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.n = 1;
+ pipe_config->dpll.m1 = 14;
+ pipe_config->dpll.m2 = 2;
+ }
+ pipe_config->clock_set = true;
} else if (IS_HASWELL(dev)) {
/* Haswell has special-purpose DP DDI clocks. */
} else if (HAS_PCH_SPLIT(dev)) {
- divisor = pch_dpll;
- count = ARRAY_SIZE(pch_dpll);
- } else if (IS_VALLEYVIEW(dev)) {
- divisor = vlv_dpll;
- count = ARRAY_SIZE(vlv_dpll);
- }
-
- if (divisor && count) {
- for (i = 0; i < count; i++) {
- if (link_bw == divisor[i].link_bw) {
- pipe_config->dpll = divisor[i].dpll;
- pipe_config->clock_set = true;
- break;
- }
+ if (link_bw == DP_LINK_BW_1_62) {
+ pipe_config->dpll.n = 1;
+ pipe_config->dpll.p1 = 2;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.m1 = 12;
+ pipe_config->dpll.m2 = 9;
+ } else {
+ pipe_config->dpll.n = 2;
+ pipe_config->dpll.p1 = 1;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.m1 = 14;
+ pipe_config->dpll.m2 = 8;
}
+ pipe_config->clock_set = true;
+ } else if (IS_VALLEYVIEW(dev)) {
+ /* FIXME: Need to figure out optimized DP clocks for vlv. */
}
}
@@ -830,22 +737,19 @@ intel_dp_compute_config(struct intel_encoder *encoder,
DRM_DEBUG_KMS("DP link computation with max lane count %i "
"max bw %02x pixel clock %iKHz\n",
- max_lane_count, bws[max_clock],
- adjusted_mode->crtc_clock);
+ max_lane_count, bws[max_clock], adjusted_mode->clock);
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
* bpc in between. */
bpp = pipe_config->pipe_bpp;
- if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp &&
- dev_priv->vbt.edp_bpp < bpp) {
+ if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp) {
DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
dev_priv->vbt.edp_bpp);
- bpp = dev_priv->vbt.edp_bpp;
+ bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp);
}
for (; bpp >= 6*3; bpp -= 2*3) {
- mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
- bpp);
+ mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
for (clock = 0; clock <= max_clock; clock++) {
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
@@ -890,8 +794,7 @@ found:
mode_rate, link_avail);
intel_link_compute_m_n(bpp, lane_count,
- adjusted_mode->crtc_clock,
- pipe_config->port_clock,
+ adjusted_mode->clock, pipe_config->port_clock,
&pipe_config->dp_m_n);
intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
@@ -899,6 +802,21 @@ found:
return true;
}
+void intel_dp_init_link_config(struct intel_dp *intel_dp)
+{
+ memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
+ intel_dp->link_configuration[0] = intel_dp->link_bw;
+ intel_dp->link_configuration[1] = intel_dp->lane_count;
+ intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B;
+ /*
+ * Check for DPCD version > 1.1 and enhanced framing support
+ */
+ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+ (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
+ intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+ }
+}
+
static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -971,6 +889,8 @@ static void intel_dp_mode_set(struct intel_encoder *encoder)
intel_write_eld(&encoder->base, adjusted_mode);
}
+ intel_dp_init_link_config(intel_dp);
+
/* Split out the IBX/CPU vs CPT settings */
if (port == PORT_A && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) {
@@ -980,7 +900,7 @@ static void intel_dp_mode_set(struct intel_encoder *encoder)
intel_dp->DP |= DP_SYNC_VS_HIGH;
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
- if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+ if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
intel_dp->DP |= DP_ENHANCED_FRAMING;
intel_dp->DP |= crtc->pipe << 29;
@@ -994,7 +914,7 @@ static void intel_dp_mode_set(struct intel_encoder *encoder)
intel_dp->DP |= DP_SYNC_VS_HIGH;
intel_dp->DP |= DP_LINK_TRAIN_OFF;
- if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+ if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
intel_dp->DP |= DP_ENHANCED_FRAMING;
if (crtc->pipe == 1)
@@ -1024,8 +944,8 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp_stat_reg, pp_ctrl_reg;
- pp_stat_reg = _pp_stat_reg(intel_dp);
- pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+ pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
mask, value,
@@ -1067,8 +987,11 @@ static u32 ironlake_get_pp_control(struct intel_dp *intel_dp)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
u32 control;
+ u32 pp_ctrl_reg;
+
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+ control = I915_READ(pp_ctrl_reg);
- control = I915_READ(_pp_ctrl_reg(intel_dp));
control &= ~PANEL_UNLOCK_MASK;
control |= PANEL_UNLOCK_REGS;
return control;
@@ -1083,16 +1006,17 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
if (!is_edp(intel_dp))
return;
+ DRM_DEBUG_KMS("Turn eDP VDD on\n");
WARN(intel_dp->want_panel_vdd,
"eDP VDD already requested on\n");
intel_dp->want_panel_vdd = true;
- if (ironlake_edp_have_panel_vdd(intel_dp))
+ if (ironlake_edp_have_panel_vdd(intel_dp)) {
+ DRM_DEBUG_KMS("eDP VDD already on\n");
return;
-
- DRM_DEBUG_KMS("Turning eDP VDD on\n");
+ }
if (!ironlake_edp_have_panel_power(intel_dp))
ironlake_wait_panel_power_cycle(intel_dp);
@@ -1100,8 +1024,8 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
pp = ironlake_get_pp_control(intel_dp);
pp |= EDP_FORCE_VDD;
- pp_stat_reg = _pp_stat_reg(intel_dp);
- pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+ pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
@@ -1126,13 +1050,11 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
- DRM_DEBUG_KMS("Turning eDP VDD off\n");
-
pp = ironlake_get_pp_control(intel_dp);
pp &= ~EDP_FORCE_VDD;
- pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
- pp_stat_reg = _pp_stat_reg(intel_dp);
+ pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
@@ -1160,6 +1082,7 @@ void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
if (!is_edp(intel_dp))
return;
+ DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd);
WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on");
intel_dp->want_panel_vdd = false;
@@ -1196,19 +1119,20 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp)
ironlake_wait_panel_power_cycle(intel_dp);
- pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
pp = ironlake_get_pp_control(intel_dp);
if (IS_GEN5(dev)) {
/* ILK workaround: disable reset around power sequence */
pp &= ~PANEL_POWER_RESET;
- I915_WRITE(pp_ctrl_reg, pp);
- POSTING_READ(pp_ctrl_reg);
+ I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
}
pp |= POWER_TARGET_ON;
if (!IS_GEN5(dev))
pp |= PANEL_POWER_RESET;
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
@@ -1216,8 +1140,8 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp)
if (IS_GEN5(dev)) {
pp |= PANEL_POWER_RESET; /* restore panel reset bit */
- I915_WRITE(pp_ctrl_reg, pp);
- POSTING_READ(pp_ctrl_reg);
+ I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
}
}
@@ -1240,7 +1164,7 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
* panels get very unhappy and cease to work. */
pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
- pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
@@ -1255,6 +1179,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
u32 pp;
u32 pp_ctrl_reg;
@@ -1272,12 +1197,12 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
pp = ironlake_get_pp_control(intel_dp);
pp |= EDP_BLC_ENABLE;
- pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
- intel_panel_enable_backlight(intel_dp->attached_connector);
+ intel_panel_enable_backlight(dev, pipe);
}
void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
@@ -1290,13 +1215,13 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
if (!is_edp(intel_dp))
return;
- intel_panel_disable_backlight(intel_dp->attached_connector);
+ intel_panel_disable_backlight(dev);
DRM_DEBUG_KMS("\n");
pp = ironlake_get_pp_control(intel_dp);
pp &= ~EDP_BLC_ENABLE;
- pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+ pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
@@ -1443,7 +1368,6 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
enum port port = dp_to_dig_port(intel_dp)->port;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
- int dotclock;
if ((port == PORT_A) || !HAS_PCH_CPT(dev)) {
tmp = I915_READ(intel_dp->output_reg);
@@ -1471,25 +1395,13 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
pipe_config->adjusted_mode.flags |= flags;
- pipe_config->has_dp_encoder = true;
-
- intel_dp_get_m_n(crtc, pipe_config);
-
- if (port == PORT_A) {
+ if (dp_to_dig_port(intel_dp)->port == PORT_A) {
if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ)
pipe_config->port_clock = 162000;
else
pipe_config->port_clock = 270000;
}
- dotclock = intel_dotclock_calculate(pipe_config->port_clock,
- &pipe_config->dp_m_n);
-
- if (HAS_PCH_SPLIT(dev_priv->dev) && port != PORT_A)
- ironlake_check_encoder_dotclock(pipe_config, dotclock);
-
- pipe_config->adjusted_mode.crtc_clock = dotclock;
-
if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp &&
pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
/*
@@ -1511,21 +1423,20 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
}
}
-static bool is_edp_psr(struct drm_device *dev)
+static bool is_edp_psr(struct intel_dp *intel_dp)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- return dev_priv->psr.sink_support;
+ return is_edp(intel_dp) &&
+ intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
}
static bool intel_edp_is_psr_enabled(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!HAS_PSR(dev))
+ if (!IS_HASWELL(dev))
return false;
- return I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE;
+ return I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE;
}
static void intel_edp_psr_write_vsc(struct intel_dp *intel_dp,
@@ -1575,7 +1486,7 @@ static void intel_edp_psr_setup(struct intel_dp *intel_dp)
intel_edp_psr_write_vsc(intel_dp, &psr_vsc);
/* Avoid continuous PSR exit by masking memup and hpd */
- I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP |
+ I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP |
EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
intel_dp->psr_setup_done = true;
@@ -1600,9 +1511,9 @@ static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp)
DP_PSR_MAIN_LINK_ACTIVE);
/* Setup AUX registers */
- I915_WRITE(EDP_PSR_AUX_DATA1(dev), EDP_PSR_DPCD_COMMAND);
- I915_WRITE(EDP_PSR_AUX_DATA2(dev), EDP_PSR_DPCD_NORMAL_OPERATION);
- I915_WRITE(EDP_PSR_AUX_CTL(dev),
+ I915_WRITE(EDP_PSR_AUX_DATA1, EDP_PSR_DPCD_COMMAND);
+ I915_WRITE(EDP_PSR_AUX_DATA2, EDP_PSR_DPCD_NORMAL_OPERATION);
+ I915_WRITE(EDP_PSR_AUX_CTL,
DP_AUX_CH_CTL_TIME_OUT_400us |
(msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
(precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
@@ -1616,7 +1527,6 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp)
uint32_t max_sleep_time = 0x1f;
uint32_t idle_frames = 1;
uint32_t val = 0x0;
- const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) {
val |= EDP_PSR_LINK_STANDBY;
@@ -1626,8 +1536,8 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp)
} else
val |= EDP_PSR_LINK_DISABLE;
- I915_WRITE(EDP_PSR_CTL(dev), val |
- IS_BROADWELL(dev) ? 0 : link_entry_time |
+ I915_WRITE(EDP_PSR_CTL, val |
+ EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES |
max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT |
idle_frames << EDP_PSR_IDLE_FRAME_SHIFT |
EDP_PSR_ENABLE);
@@ -1643,33 +1553,42 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj;
struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
- dev_priv->psr.source_ok = false;
-
- if (!HAS_PSR(dev)) {
+ if (!IS_HASWELL(dev)) {
DRM_DEBUG_KMS("PSR not supported on this platform\n");
+ dev_priv->no_psr_reason = PSR_NO_SOURCE;
return false;
}
if ((intel_encoder->type != INTEL_OUTPUT_EDP) ||
(dig_port->port != PORT_A)) {
DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n");
+ dev_priv->no_psr_reason = PSR_HSW_NOT_DDIA;
+ return false;
+ }
+
+ if (!is_edp_psr(intel_dp)) {
+ DRM_DEBUG_KMS("PSR not supported by this panel\n");
+ dev_priv->no_psr_reason = PSR_NO_SINK;
return false;
}
if (!i915_enable_psr) {
DRM_DEBUG_KMS("PSR disable by flag\n");
+ dev_priv->no_psr_reason = PSR_MODULE_PARAM;
return false;
}
crtc = dig_port->base.base.crtc;
if (crtc == NULL) {
DRM_DEBUG_KMS("crtc not active for PSR\n");
+ dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE;
return false;
}
intel_crtc = to_intel_crtc(crtc);
- if (!intel_crtc_active(crtc)) {
+ if (!intel_crtc->active || !crtc->fb || !crtc->mode.clock) {
DRM_DEBUG_KMS("crtc not active for PSR\n");
+ dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE;
return false;
}
@@ -1677,26 +1596,29 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
if (obj->tiling_mode != I915_TILING_X ||
obj->fence_reg == I915_FENCE_REG_NONE) {
DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n");
+ dev_priv->no_psr_reason = PSR_NOT_TILED;
return false;
}
if (I915_READ(SPRCTL(intel_crtc->pipe)) & SPRITE_ENABLE) {
DRM_DEBUG_KMS("PSR condition failed: Sprite is Enabled\n");
+ dev_priv->no_psr_reason = PSR_SPRITE_ENABLED;
return false;
}
if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) &
S3D_ENABLE) {
DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
+ dev_priv->no_psr_reason = PSR_S3D_ENABLED;
return false;
}
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+ if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
+ dev_priv->no_psr_reason = PSR_INTERLACED_ENABLED;
return false;
}
- dev_priv->psr.source_ok = true;
return true;
}
@@ -1735,11 +1657,10 @@ void intel_edp_psr_disable(struct intel_dp *intel_dp)
if (!intel_edp_is_psr_enabled(dev))
return;
- I915_WRITE(EDP_PSR_CTL(dev),
- I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE);
+ I915_WRITE(EDP_PSR_CTL, I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE);
/* Wait till PSR is idle */
- if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) &
+ if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
DRM_ERROR("Timed out waiting for PSR Idle State\n");
}
@@ -1753,7 +1674,7 @@ void intel_edp_psr_update(struct drm_device *dev)
if (encoder->type == INTEL_OUTPUT_EDP) {
intel_dp = enc_to_intel_dp(&encoder->base);
- if (!is_edp_psr(dev))
+ if (!is_edp_psr(intel_dp))
return;
if (!intel_edp_psr_match_conditions(intel_dp))
@@ -1774,7 +1695,7 @@ static void intel_disable_dp(struct intel_encoder *encoder)
* ensure that we have vdd while we switch off the panel. */
ironlake_edp_panel_vdd_on(intel_dp);
ironlake_edp_backlight_off(intel_dp);
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+ intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
ironlake_edp_panel_off(intel_dp);
/* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */
@@ -1812,24 +1733,14 @@ static void intel_enable_dp(struct intel_encoder *encoder)
ironlake_edp_panel_vdd_off(intel_dp, true);
intel_dp_complete_link_train(intel_dp);
intel_dp_stop_link_train(intel_dp);
-}
-
-static void g4x_enable_dp(struct intel_encoder *encoder)
-{
- struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-
- intel_enable_dp(encoder);
ironlake_edp_backlight_on(intel_dp);
}
static void vlv_enable_dp(struct intel_encoder *encoder)
{
- struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-
- ironlake_edp_backlight_on(intel_dp);
}
-static void g4x_pre_enable_dp(struct intel_encoder *encoder)
+static void intel_pre_enable_dp(struct intel_encoder *encoder)
{
struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
@@ -1847,59 +1758,53 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
int port = vlv_dport_to_channel(dport);
int pipe = intel_crtc->pipe;
- struct edp_power_seq power_seq;
u32 val;
mutex_lock(&dev_priv->dpio_lock);
- val = vlv_dpio_read(dev_priv, pipe, DPIO_DATA_LANE_A(port));
+ val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port));
val = 0;
if (pipe)
val |= (1<<21);
else
val &= ~(1<<21);
val |= 0x001000c4;
- vlv_dpio_write(dev_priv, pipe, DPIO_DATA_CHANNEL(port), val);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF0(port), 0x00760018);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF8(port), 0x00400888);
+ vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val);
+ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), 0x00760018);
+ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), 0x00400888);
mutex_unlock(&dev_priv->dpio_lock);
- /* init power sequencer on this pipe and port */
- intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
- &power_seq);
-
intel_enable_dp(encoder);
vlv_wait_port_ready(dev_priv, port);
}
-static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
+static void intel_dp_pre_pll_enable(struct intel_encoder *encoder)
{
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc =
- to_intel_crtc(encoder->base.crtc);
int port = vlv_dport_to_channel(dport);
- int pipe = intel_crtc->pipe;
+
+ if (!IS_VALLEYVIEW(dev))
+ return;
/* Program Tx lane resets to default */
mutex_lock(&dev_priv->dpio_lock);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_TX(port),
DPIO_PCS_TX_LANE2_RESET |
DPIO_PCS_TX_LANE1_RESET);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port),
DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
(1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
DPIO_PCS_CLK_SOFT_RESET);
/* Fix up inter-pair skew failure */
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);
+ vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00);
+ vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500);
+ vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000);
mutex_unlock(&dev_priv->dpio_lock);
}
@@ -1964,7 +1869,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
enum port port = dp_to_dig_port(intel_dp)->port;
- if (IS_VALLEYVIEW(dev) || IS_BROADWELL(dev))
+ if (IS_VALLEYVIEW(dev))
return DP_TRAIN_VOLTAGE_SWING_1200;
else if (IS_GEN7(dev) && port == PORT_A)
return DP_TRAIN_VOLTAGE_SWING_800;
@@ -1980,18 +1885,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
enum port port = dp_to_dig_port(intel_dp)->port;
- if (IS_BROADWELL(dev)) {
- switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
- case DP_TRAIN_VOLTAGE_SWING_400:
- case DP_TRAIN_VOLTAGE_SWING_600:
- return DP_TRAIN_PRE_EMPHASIS_6;
- case DP_TRAIN_VOLTAGE_SWING_800:
- return DP_TRAIN_PRE_EMPHASIS_3_5;
- case DP_TRAIN_VOLTAGE_SWING_1200:
- default:
- return DP_TRAIN_PRE_EMPHASIS_0;
- }
- } else if (IS_HASWELL(dev)) {
+ if (HAS_DDI(dev)) {
switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
case DP_TRAIN_VOLTAGE_SWING_400:
return DP_TRAIN_PRE_EMPHASIS_9_5;
@@ -2045,13 +1939,10 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
- struct intel_crtc *intel_crtc =
- to_intel_crtc(dport->base.base.crtc);
unsigned long demph_reg_value, preemph_reg_value,
uniqtranscale_reg_value;
uint8_t train_set = intel_dp->train_set[0];
int port = vlv_dport_to_channel(dport);
- int pipe = intel_crtc->pipe;
switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
case DP_TRAIN_PRE_EMPHASIS_0:
@@ -2127,22 +2018,21 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
}
mutex_lock(&dev_priv->dpio_lock);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x00000000);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL4(port), demph_reg_value);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL2(port),
+ vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x00000000);
+ vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), demph_reg_value);
+ vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port),
uniqtranscale_reg_value);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL3(port), 0x0C782040);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER0(port), 0x00030000);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x80000000);
+ vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), 0x0C782040);
+ vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000);
+ vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
+ vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x80000000);
mutex_unlock(&dev_priv->dpio_lock);
return 0;
}
static void
-intel_get_adjust_train(struct intel_dp *intel_dp,
- const uint8_t link_status[DP_LINK_STATUS_SIZE])
+intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
{
uint8_t v = 0;
uint8_t p = 0;
@@ -2303,41 +2193,6 @@ intel_hsw_signal_levels(uint8_t train_set)
}
}
-static uint32_t
-intel_bdw_signal_levels(uint8_t train_set)
-{
- int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
- DP_TRAIN_PRE_EMPHASIS_MASK);
- switch (signal_levels) {
- case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_400MV_0DB_BDW; /* Sel0 */
- case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
- return DDI_BUF_EMP_400MV_3_5DB_BDW; /* Sel1 */
- case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
- return DDI_BUF_EMP_400MV_6DB_BDW; /* Sel2 */
-
- case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_600MV_0DB_BDW; /* Sel3 */
- case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
- return DDI_BUF_EMP_600MV_3_5DB_BDW; /* Sel4 */
- case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6:
- return DDI_BUF_EMP_600MV_6DB_BDW; /* Sel5 */
-
- case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_800MV_0DB_BDW; /* Sel6 */
- case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
- return DDI_BUF_EMP_800MV_3_5DB_BDW; /* Sel7 */
-
- case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_1200MV_0DB_BDW; /* Sel8 */
-
- default:
- DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
- "0x%x\n", signal_levels);
- return DDI_BUF_EMP_400MV_0DB_BDW; /* Sel0 */
- }
-}
-
/* Properly updates "DP" with the correct signal levels. */
static void
intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
@@ -2348,10 +2203,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
uint32_t signal_levels, mask;
uint8_t train_set = intel_dp->train_set[0];
- if (IS_BROADWELL(dev)) {
- signal_levels = intel_bdw_signal_levels(train_set);
- mask = DDI_BUF_EMP_MASK;
- } else if (IS_HASWELL(dev)) {
+ if (HAS_DDI(dev)) {
signal_levels = intel_hsw_signal_levels(train_set);
mask = DDI_BUF_EMP_MASK;
} else if (IS_VALLEYVIEW(dev)) {
@@ -2375,15 +2227,14 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
static bool
intel_dp_set_link_train(struct intel_dp *intel_dp,
- uint32_t *DP,
+ uint32_t dp_reg_value,
uint8_t dp_train_pat)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum port port = intel_dig_port->port;
- uint8_t buf[sizeof(intel_dp->train_set) + 1];
- int ret, len;
+ int ret;
if (HAS_DDI(dev)) {
uint32_t temp = I915_READ(DP_TP_CTL(port));
@@ -2412,93 +2263,62 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
I915_WRITE(DP_TP_CTL(port), temp);
} else if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) {
- *DP &= ~DP_LINK_TRAIN_MASK_CPT;
+ dp_reg_value &= ~DP_LINK_TRAIN_MASK_CPT;
switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
case DP_TRAINING_PATTERN_DISABLE:
- *DP |= DP_LINK_TRAIN_OFF_CPT;
+ dp_reg_value |= DP_LINK_TRAIN_OFF_CPT;
break;
case DP_TRAINING_PATTERN_1:
- *DP |= DP_LINK_TRAIN_PAT_1_CPT;
+ dp_reg_value |= DP_LINK_TRAIN_PAT_1_CPT;
break;
case DP_TRAINING_PATTERN_2:
- *DP |= DP_LINK_TRAIN_PAT_2_CPT;
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
break;
case DP_TRAINING_PATTERN_3:
DRM_ERROR("DP training pattern 3 not supported\n");
- *DP |= DP_LINK_TRAIN_PAT_2_CPT;
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
break;
}
} else {
- *DP &= ~DP_LINK_TRAIN_MASK;
+ dp_reg_value &= ~DP_LINK_TRAIN_MASK;
switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
case DP_TRAINING_PATTERN_DISABLE:
- *DP |= DP_LINK_TRAIN_OFF;
+ dp_reg_value |= DP_LINK_TRAIN_OFF;
break;
case DP_TRAINING_PATTERN_1:
- *DP |= DP_LINK_TRAIN_PAT_1;
+ dp_reg_value |= DP_LINK_TRAIN_PAT_1;
break;
case DP_TRAINING_PATTERN_2:
- *DP |= DP_LINK_TRAIN_PAT_2;
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2;
break;
case DP_TRAINING_PATTERN_3:
DRM_ERROR("DP training pattern 3 not supported\n");
- *DP |= DP_LINK_TRAIN_PAT_2;
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2;
break;
}
}
- I915_WRITE(intel_dp->output_reg, *DP);
+ I915_WRITE(intel_dp->output_reg, dp_reg_value);
POSTING_READ(intel_dp->output_reg);
- buf[0] = dp_train_pat;
- if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
+ intel_dp_aux_native_write_1(intel_dp,
+ DP_TRAINING_PATTERN_SET,
+ dp_train_pat);
+
+ if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) !=
DP_TRAINING_PATTERN_DISABLE) {
- /* don't write DP_TRAINING_LANEx_SET on disable */
- len = 1;
- } else {
- /* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */
- memcpy(buf + 1, intel_dp->train_set, intel_dp->lane_count);
- len = intel_dp->lane_count + 1;
+ ret = intel_dp_aux_native_write(intel_dp,
+ DP_TRAINING_LANE0_SET,
+ intel_dp->train_set,
+ intel_dp->lane_count);
+ if (ret != intel_dp->lane_count)
+ return false;
}
- ret = intel_dp_aux_native_write(intel_dp, DP_TRAINING_PATTERN_SET,
- buf, len);
-
- return ret == len;
-}
-
-static bool
-intel_dp_reset_link_train(struct intel_dp *intel_dp, uint32_t *DP,
- uint8_t dp_train_pat)
-{
- memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
- intel_dp_set_signal_levels(intel_dp, DP);
- return intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
-}
-
-static bool
-intel_dp_update_link_train(struct intel_dp *intel_dp, uint32_t *DP,
- const uint8_t link_status[DP_LINK_STATUS_SIZE])
-{
- struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
- struct drm_device *dev = intel_dig_port->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int ret;
-
- intel_get_adjust_train(intel_dp, link_status);
- intel_dp_set_signal_levels(intel_dp, DP);
-
- I915_WRITE(intel_dp->output_reg, *DP);
- POSTING_READ(intel_dp->output_reg);
-
- ret = intel_dp_aux_native_write(intel_dp, DP_TRAINING_LANE0_SET,
- intel_dp->train_set,
- intel_dp->lane_count);
-
- return ret == intel_dp->lane_count;
+ return true;
}
static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
@@ -2542,37 +2362,32 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
uint8_t voltage;
int voltage_tries, loop_tries;
uint32_t DP = intel_dp->DP;
- uint8_t link_config[2];
if (HAS_DDI(dev))
intel_ddi_prepare_link_retrain(encoder);
/* Write the link configuration data */
- link_config[0] = intel_dp->link_bw;
- link_config[1] = intel_dp->lane_count;
- if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
- link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
- intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, link_config, 2);
-
- link_config[0] = 0;
- link_config[1] = DP_SET_ANSI_8B10B;
- intel_dp_aux_native_write(intel_dp, DP_DOWNSPREAD_CTRL, link_config, 2);
+ intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
+ intel_dp->link_configuration,
+ DP_LINK_CONFIGURATION_SIZE);
DP |= DP_PORT_EN;
- /* clock recovery */
- if (!intel_dp_reset_link_train(intel_dp, &DP,
- DP_TRAINING_PATTERN_1 |
- DP_LINK_SCRAMBLING_DISABLE)) {
- DRM_ERROR("failed to enable link training\n");
- return;
- }
-
+ memset(intel_dp->train_set, 0, 4);
voltage = 0xff;
voltage_tries = 0;
loop_tries = 0;
for (;;) {
- uint8_t link_status[DP_LINK_STATUS_SIZE];
+ /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
+ uint8_t link_status[DP_LINK_STATUS_SIZE];
+
+ intel_dp_set_signal_levels(intel_dp, &DP);
+
+ /* Set training pattern 1 */
+ if (!intel_dp_set_link_train(intel_dp, DP,
+ DP_TRAINING_PATTERN_1 |
+ DP_LINK_SCRAMBLING_DISABLE))
+ break;
drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
if (!intel_dp_get_link_status(intel_dp, link_status)) {
@@ -2592,12 +2407,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
if (i == intel_dp->lane_count) {
++loop_tries;
if (loop_tries == 5) {
- DRM_ERROR("too many full retries, give up\n");
+ DRM_DEBUG_KMS("too many full retries, give up\n");
break;
}
- intel_dp_reset_link_train(intel_dp, &DP,
- DP_TRAINING_PATTERN_1 |
- DP_LINK_SCRAMBLING_DISABLE);
+ memset(intel_dp->train_set, 0, 4);
voltage_tries = 0;
continue;
}
@@ -2606,18 +2419,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
++voltage_tries;
if (voltage_tries == 5) {
- DRM_ERROR("too many voltage retries, give up\n");
+ DRM_DEBUG_KMS("too many voltage retries, give up\n");
break;
}
} else
voltage_tries = 0;
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
- /* Update training set as requested by target */
- if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
- DRM_ERROR("failed to update link training\n");
- break;
- }
+ /* Compute new intel_dp->train_set as requested by target */
+ intel_get_adjust_train(intel_dp, link_status);
}
intel_dp->DP = DP;
@@ -2631,18 +2441,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
uint32_t DP = intel_dp->DP;
/* channel equalization */
- if (!intel_dp_set_link_train(intel_dp, &DP,
- DP_TRAINING_PATTERN_2 |
- DP_LINK_SCRAMBLING_DISABLE)) {
- DRM_ERROR("failed to start channel equalization\n");
- return;
- }
-
tries = 0;
cr_tries = 0;
channel_eq = false;
for (;;) {
- uint8_t link_status[DP_LINK_STATUS_SIZE];
+ uint8_t link_status[DP_LINK_STATUS_SIZE];
if (cr_tries > 5) {
DRM_ERROR("failed to train DP, aborting\n");
@@ -2650,18 +2453,21 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
break;
}
+ intel_dp_set_signal_levels(intel_dp, &DP);
+
+ /* channel eq pattern */
+ if (!intel_dp_set_link_train(intel_dp, DP,
+ DP_TRAINING_PATTERN_2 |
+ DP_LINK_SCRAMBLING_DISABLE))
+ break;
+
drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
- if (!intel_dp_get_link_status(intel_dp, link_status)) {
- DRM_ERROR("failed to get link status\n");
+ if (!intel_dp_get_link_status(intel_dp, link_status))
break;
- }
/* Make sure clock is still ok */
if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
intel_dp_start_link_train(intel_dp);
- intel_dp_set_link_train(intel_dp, &DP,
- DP_TRAINING_PATTERN_2 |
- DP_LINK_SCRAMBLING_DISABLE);
cr_tries++;
continue;
}
@@ -2675,19 +2481,13 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
if (tries > 5) {
intel_dp_link_down(intel_dp);
intel_dp_start_link_train(intel_dp);
- intel_dp_set_link_train(intel_dp, &DP,
- DP_TRAINING_PATTERN_2 |
- DP_LINK_SCRAMBLING_DISABLE);
tries = 0;
cr_tries++;
continue;
}
- /* Update training set as requested by target */
- if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
- DRM_ERROR("failed to update link training\n");
- break;
- }
+ /* Compute new intel_dp->train_set as requested by target */
+ intel_get_adjust_train(intel_dp, link_status);
++tries;
}
@@ -2702,7 +2502,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
void intel_dp_stop_link_train(struct intel_dp *intel_dp)
{
- intel_dp_set_link_train(intel_dp, &intel_dp->DP,
+ intel_dp_set_link_train(intel_dp, intel_dp->DP,
DP_TRAINING_PATTERN_DISABLE);
}
@@ -2789,10 +2589,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
static bool
intel_dp_get_dpcd(struct intel_dp *intel_dp)
{
- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
- struct drm_device *dev = dig_port->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
char dpcd_hex_dump[sizeof(intel_dp->dpcd) * 3];
if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd,
@@ -2808,16 +2604,11 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
/* Check if the panel supports PSR */
memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd));
- if (is_edp(intel_dp)) {
- intel_dp_aux_native_read_retry(intel_dp, DP_PSR_SUPPORT,
- intel_dp->psr_dpcd,
- sizeof(intel_dp->psr_dpcd));
- if (intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED) {
- dev_priv->psr.sink_support = true;
- DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
- }
- }
-
+ intel_dp_aux_native_read_retry(intel_dp, DP_PSR_SUPPORT,
+ intel_dp->psr_dpcd,
+ sizeof(intel_dp->psr_dpcd));
+ if (is_edp_psr(intel_dp))
+ DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
DP_DWN_STRM_PORT_PRESENT))
return true; /* native DP sink */
@@ -2937,6 +2728,7 @@ static enum drm_connector_status
intel_dp_detect_dpcd(struct intel_dp *intel_dp)
{
uint8_t *dpcd = intel_dp->dpcd;
+ bool hpd;
uint8_t type;
if (!intel_dp_get_dpcd(intel_dp))
@@ -2947,8 +2739,8 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
return connector_status_connected;
/* If we're HPD-aware, SINK_COUNT changes dynamically */
- if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
- intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) {
+ hpd = !!(intel_dp->downstream_ports[0] & DP_DS_PORT_HPD);
+ if (hpd) {
uint8_t reg;
if (!intel_dp_aux_native_read_retry(intel_dp, DP_SINK_COUNT,
&reg, 1))
@@ -2962,18 +2754,9 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
return connector_status_connected;
/* Well we tried, say unknown for unreliable port types */
- if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
- type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
- if (type == DP_DS_PORT_TYPE_VGA ||
- type == DP_DS_PORT_TYPE_NON_EDID)
- return connector_status_unknown;
- } else {
- type = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
- DP_DWN_STRM_PORT_TYPE_MASK;
- if (type == DP_DWN_STRM_PORT_TYPE_ANALOG ||
- type == DP_DWN_STRM_PORT_TYPE_OTHER)
- return connector_status_unknown;
- }
+ type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
+ if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_NON_EDID)
+ return connector_status_unknown;
/* Anything else is out of spec, warn and ignore */
DRM_DEBUG_KMS("Broken DP branch device, ignoring\n");
@@ -3047,11 +2830,19 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
/* use cached edid if we have one */
if (intel_connector->edid) {
+ struct edid *edid;
+ int size;
+
/* invalid edid */
if (IS_ERR(intel_connector->edid))
return NULL;
- return drm_edid_duplicate(intel_connector->edid);
+ size = (intel_connector->edid->extensions + 1) * EDID_LENGTH;
+ edid = kmemdup(intel_connector->edid, size, GFP_KERNEL);
+ if (!edid)
+ return NULL;
+
+ return edid;
}
return drm_get_edid(connector, adapter);
@@ -3259,6 +3050,7 @@ intel_dp_connector_destroy(struct drm_connector *connector)
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
intel_panel_fini(&intel_connector->panel);
+ drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -3326,19 +3118,11 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
}
/* check the VBT to see whether the eDP is on DP-D port */
-bool intel_dp_is_edp(struct drm_device *dev, enum port port)
+bool intel_dpd_is_edp(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- union child_device_config *p_child;
+ struct child_device_config *p_child;
int i;
- static const short port_mapping[] = {
- [PORT_B] = PORT_IDPB,
- [PORT_C] = PORT_IDPC,
- [PORT_D] = PORT_IDPD,
- };
-
- if (port == PORT_A)
- return true;
if (!dev_priv->vbt.child_dev_num)
return false;
@@ -3346,9 +3130,8 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port)
for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
p_child = dev_priv->vbt.child_dev + i;
- if (p_child->common.dvo_port == port_mapping[port] &&
- (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) ==
- (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
+ if (p_child->dvo_port == PORT_IDPD &&
+ p_child->device_type == DEVICE_TYPE_eDP)
return true;
}
return false;
@@ -3381,26 +3164,24 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private;
struct edp_power_seq cur, vbt, spec, final;
u32 pp_on, pp_off, pp_div, pp;
- int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
+ int pp_control_reg, pp_on_reg, pp_off_reg, pp_div_reg;
if (HAS_PCH_SPLIT(dev)) {
- pp_ctrl_reg = PCH_PP_CONTROL;
+ pp_control_reg = PCH_PP_CONTROL;
pp_on_reg = PCH_PP_ON_DELAYS;
pp_off_reg = PCH_PP_OFF_DELAYS;
pp_div_reg = PCH_PP_DIVISOR;
} else {
- enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
-
- pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
- pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
- pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
- pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
+ pp_control_reg = PIPEA_PP_CONTROL;
+ pp_on_reg = PIPEA_PP_ON_DELAYS;
+ pp_off_reg = PIPEA_PP_OFF_DELAYS;
+ pp_div_reg = PIPEA_PP_DIVISOR;
}
/* Workaround: Need to write PP_CONTROL with the unlock key as
* the very first thing. */
pp = ironlake_get_pp_control(intel_dp);
- I915_WRITE(pp_ctrl_reg, pp);
+ I915_WRITE(pp_control_reg, pp);
pp_on = I915_READ(pp_on_reg);
pp_off = I915_READ(pp_off_reg);
@@ -3488,11 +3269,9 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
pp_off_reg = PCH_PP_OFF_DELAYS;
pp_div_reg = PCH_PP_DIVISOR;
} else {
- enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
-
- pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
- pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
- pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
+ pp_on_reg = PIPEA_PP_ON_DELAYS;
+ pp_off_reg = PIPEA_PP_OFF_DELAYS;
+ pp_div_reg = PIPEA_PP_DIVISOR;
}
/* And finally store the new values in the power sequencer. */
@@ -3509,15 +3288,12 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
/* Haswell doesn't have any port selection bits for the panel
* power sequencer any more. */
if (IS_VALLEYVIEW(dev)) {
- if (dp_to_dig_port(intel_dp)->port == PORT_B)
- port_sel = PANEL_PORT_SELECT_DPB_VLV;
- else
- port_sel = PANEL_PORT_SELECT_DPC_VLV;
+ port_sel = I915_READ(pp_on_reg) & 0xc0000000;
} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
if (dp_to_dig_port(intel_dp)->port == PORT_A)
- port_sel = PANEL_PORT_SELECT_DPA;
+ port_sel = PANEL_POWER_PORT_DP_A;
else
- port_sel = PANEL_PORT_SELECT_DPD;
+ port_sel = PANEL_POWER_PORT_DP_D;
}
pp_on |= port_sel;
@@ -3570,6 +3346,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
&power_seq);
+ ironlake_edp_panel_vdd_on(intel_dp);
edid = drm_get_edid(connector, &intel_dp->adapter);
if (edid) {
if (drm_add_edid_modes(connector, edid)) {
@@ -3601,6 +3378,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
}
+ ironlake_edp_panel_vdd_off(intel_dp, false);
+
intel_panel_init(&intel_connector->panel, fixed_mode);
intel_panel_setup_backlight(connector);
@@ -3624,10 +3403,26 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
intel_dp->DP = I915_READ(intel_dp->output_reg);
intel_dp->attached_connector = intel_connector;
- if (intel_dp_is_edp(dev, port))
+ type = DRM_MODE_CONNECTOR_DisplayPort;
+ /*
+ * FIXME : We need to initialize built-in panels before external panels.
+ * For X0, DP_C is fixed as eDP. Revisit this as part of VLV eDP cleanup
+ */
+ switch (port) {
+ case PORT_A:
type = DRM_MODE_CONNECTOR_eDP;
- else
- type = DRM_MODE_CONNECTOR_DisplayPort;
+ break;
+ case PORT_C:
+ if (IS_VALLEYVIEW(dev))
+ type = DRM_MODE_CONNECTOR_eDP;
+ break;
+ case PORT_D:
+ if (HAS_PCH_SPLIT(dev) && intel_dpd_is_edp(dev))
+ type = DRM_MODE_CONNECTOR_eDP;
+ break;
+ default: /* silence GCC warning */
+ break;
+ }
/*
* For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
@@ -3741,11 +3536,11 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
struct drm_encoder *encoder;
struct intel_connector *intel_connector;
- intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
+ intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
if (!intel_dig_port)
return;
- intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+ intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_dig_port);
return;
@@ -3764,12 +3559,12 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
intel_encoder->get_hw_state = intel_dp_get_hw_state;
intel_encoder->get_config = intel_dp_get_config;
if (IS_VALLEYVIEW(dev)) {
- intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
+ intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable;
intel_encoder->pre_enable = vlv_pre_enable_dp;
intel_encoder->enable = vlv_enable_dp;
} else {
- intel_encoder->pre_enable = g4x_pre_enable_dp;
- intel_encoder->enable = g4x_enable_dp;
+ intel_encoder->pre_enable = intel_pre_enable_dp;
+ intel_encoder->enable = intel_enable_dp;
}
intel_dig_port->port = port;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a18e88b..7f2b384 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -77,6 +77,7 @@
/* the i915, i945 have a single sDVO i2c bus - which is different */
#define MAX_OUTPUTS 6
/* maximum connectors per crtcs in the mode set */
+#define INTELFB_CONN_LIMIT 4
#define INTEL_I2C_BUS_DVO 1
#define INTEL_I2C_BUS_SDVO 2
@@ -92,17 +93,13 @@
#define INTEL_OUTPUT_HDMI 6
#define INTEL_OUTPUT_DISPLAYPORT 7
#define INTEL_OUTPUT_EDP 8
-#define INTEL_OUTPUT_DSI 9
-#define INTEL_OUTPUT_UNKNOWN 10
+#define INTEL_OUTPUT_UNKNOWN 9
#define INTEL_DVO_CHIP_NONE 0
#define INTEL_DVO_CHIP_LVDS 1
#define INTEL_DVO_CHIP_TMDS 2
#define INTEL_DVO_CHIP_TVOUT 4
-#define INTEL_DSI_COMMAND_MODE 0
-#define INTEL_DSI_VIDEO_MODE 1
-
struct intel_framebuffer {
struct drm_framebuffer base;
struct drm_i915_gem_object *obj;
@@ -210,21 +207,8 @@ struct intel_crtc_config {
#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
unsigned long quirks;
- /* User requested mode, only valid as a starting point to
- * compute adjusted_mode, except in the case of (S)DVO where
- * it's also for the output timings of the (S)DVO chip.
- * adjusted_mode will then correspond to the S(DVO) chip's
- * preferred input timings. */
struct drm_display_mode requested_mode;
- /* Actual pipe timings ie. what we program into the pipe timing
- * registers. adjusted_mode.crtc_clock is the pipe pixel clock. */
struct drm_display_mode adjusted_mode;
-
- /* Pipe source size (ie. panel fitter input size)
- * All planes will be positioned inside this space,
- * and get clipped at the edges. */
- int pipe_src_w, pipe_src_h;
-
/* Whether to set up the PCH/FDI. Note that we never allow sharing
* between pch encoders and cpu encoders. */
bool has_pch_encoder;
@@ -278,8 +262,7 @@ struct intel_crtc_config {
/*
* Frequence the dpll for the port should run at. Differs from the
- * adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also
- * already multiplied by pixel_multiplier.
+ * adjusted dotclock e.g. for DP or 12bpc hdmi mode.
*/
int port_clock;
@@ -305,14 +288,6 @@ struct intel_crtc_config {
struct intel_link_m_n fdi_m_n;
bool ips_enabled;
-
- bool double_wide;
-};
-
-struct intel_pipe_wm {
- struct intel_wm_level wm[5];
- uint32_t linetime;
- bool fbc_wm_enabled;
};
struct intel_crtc {
@@ -326,9 +301,8 @@ struct intel_crtc {
* some outputs connected to this crtc.
*/
bool active;
- unsigned long enabled_power_domains;
bool eld_vld;
- bool primary_enabled; /* is the primary plane (partially) visible? */
+ bool primary_disabled; /* is the crtc obscured by a plane? */
bool lowfreq_avail;
struct intel_overlay *overlay;
struct intel_unpin_work *unpin_work;
@@ -356,12 +330,6 @@ struct intel_crtc {
/* Access to these should be protected by dev_priv->irq_lock. */
bool cpu_fifo_underrun_disabled;
bool pch_fifo_underrun_disabled;
-
- /* per-pipe watermark state */
- struct {
- /* watermarks currently being used */
- struct intel_pipe_wm active;
- } wm;
};
struct intel_plane_wm_parameters {
@@ -449,11 +417,13 @@ struct intel_hdmi {
};
#define DP_MAX_DOWNSTREAM_PORTS 0x10
+#define DP_LINK_CONFIGURATION_SIZE 9
struct intel_dp {
uint32_t output_reg;
uint32_t aux_ch_ctl_reg;
uint32_t DP;
+ uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
bool has_audio;
enum hdmi_force_audio force_audio;
uint32_t color_range;
@@ -525,6 +495,80 @@ struct intel_unpin_work {
bool enable_stall_check;
};
+int intel_pch_rawclk(struct drm_device *dev);
+
+int intel_connector_update_modes(struct drm_connector *connector,
+ struct edid *edid);
+int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
+
+extern void intel_attach_force_audio_property(struct drm_connector *connector);
+extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
+
+extern bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
+extern void intel_crt_init(struct drm_device *dev);
+extern void intel_hdmi_init(struct drm_device *dev,
+ int hdmi_reg, enum port port);
+extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+ struct intel_connector *intel_connector);
+extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
+extern bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config);
+extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
+ bool is_sdvob);
+extern void intel_dvo_init(struct drm_device *dev);
+extern void intel_tv_init(struct drm_device *dev);
+extern void intel_mark_busy(struct drm_device *dev);
+extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
+ struct intel_ring_buffer *ring);
+extern void intel_mark_idle(struct drm_device *dev);
+extern void intel_lvds_init(struct drm_device *dev);
+extern bool intel_is_dual_link_lvds(struct drm_device *dev);
+extern void intel_dp_init(struct drm_device *dev, int output_reg,
+ enum port port);
+extern bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
+ struct intel_connector *intel_connector);
+extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
+extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
+extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
+extern void intel_dp_stop_link_train(struct intel_dp *intel_dp);
+extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
+extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
+extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
+extern bool intel_dp_compute_config(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config);
+extern bool intel_dpd_is_edp(struct drm_device *dev);
+extern void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
+extern void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
+extern void ironlake_edp_panel_on(struct intel_dp *intel_dp);
+extern void ironlake_edp_panel_off(struct intel_dp *intel_dp);
+extern void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp);
+extern void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
+extern int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
+extern void intel_flush_display_plane(struct drm_i915_private *dev_priv,
+ enum plane plane);
+
+/* intel_panel.c */
+extern int intel_panel_init(struct intel_panel *panel,
+ struct drm_display_mode *fixed_mode);
+extern void intel_panel_fini(struct intel_panel *panel);
+
+extern void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *adjusted_mode);
+extern void intel_pch_panel_fitting(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config,
+ int fitting_mode);
+extern void intel_gmch_panel_fitting(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config,
+ int fitting_mode);
+extern void intel_panel_set_backlight(struct drm_device *dev,
+ u32 level, u32 max);
+extern int intel_panel_setup_backlight(struct drm_connector *connector);
+extern void intel_panel_enable_backlight(struct drm_device *dev,
+ enum pipe pipe);
+extern void intel_panel_disable_backlight(struct drm_device *dev);
+extern void intel_panel_destroy_backlight(struct drm_device *dev);
+extern enum drm_connector_status intel_panel_detect(struct drm_device *dev);
+
struct intel_set_config {
struct drm_encoder **save_connector_encoders;
struct drm_crtc **save_encoder_crtcs;
@@ -533,14 +577,18 @@ struct intel_set_config {
bool mode_changed;
};
-struct intel_load_detect_pipe {
- struct drm_framebuffer *release_fb;
- bool load_detect_temp;
- int dpms_mode;
-};
+extern void intel_crtc_restore_mode(struct drm_crtc *crtc);
+extern void intel_crtc_load_lut(struct drm_crtc *crtc);
+extern void intel_crtc_update_dpms(struct drm_crtc *crtc);
+extern void intel_encoder_destroy(struct drm_encoder *encoder);
+extern void intel_connector_dpms(struct drm_connector *, int mode);
+extern bool intel_connector_get_hw_state(struct intel_connector *connector);
+extern void intel_modeset_check_state(struct drm_device *dev);
+extern void intel_plane_restore(struct drm_plane *plane);
+extern void intel_plane_disable(struct drm_plane *plane);
+
-static inline struct intel_encoder *
-intel_attached_encoder(struct drm_connector *connector)
+static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector)
{
return to_intel_connector(connector)->encoder;
}
@@ -568,95 +616,73 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
return container_of(intel_hdmi, struct intel_digital_port, hdmi);
}
-
-/* i915_irq.c */
-bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
- enum pipe pipe, bool enable);
-bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
- enum transcoder pch_transcoder,
- bool enable);
-void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void hsw_pc8_disable_interrupts(struct drm_device *dev);
-void hsw_pc8_restore_interrupts(struct drm_device *dev);
-
-
-/* intel_crt.c */
-void intel_crt_init(struct drm_device *dev);
-
-
-/* intel_ddi.c */
-void intel_prepare_ddi(struct drm_device *dev);
-void hsw_fdi_link_train(struct drm_crtc *crtc);
-void intel_ddi_init(struct drm_device *dev, enum port port);
-enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
-bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
-int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv);
-void intel_ddi_pll_init(struct drm_device *dev);
-void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
-void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
- enum transcoder cpu_transcoder);
-void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
-void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
-void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
-bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
-void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
-void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
-void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
-bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
-void intel_ddi_fdi_disable(struct drm_crtc *crtc);
-void intel_ddi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config);
-
-
-/* intel_display.c */
-int intel_pch_rawclk(struct drm_device *dev);
-void intel_mark_busy(struct drm_device *dev);
-void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *ring);
-void intel_mark_idle(struct drm_device *dev);
-void intel_crtc_restore_mode(struct drm_crtc *crtc);
-void intel_crtc_update_dpms(struct drm_crtc *crtc);
-void intel_encoder_destroy(struct drm_encoder *encoder);
-void intel_connector_dpms(struct drm_connector *, int mode);
-bool intel_connector_get_hw_state(struct intel_connector *connector);
-void intel_modeset_check_state(struct drm_device *dev);
bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
struct intel_digital_port *port);
-void intel_connector_attach_encoder(struct intel_connector *connector,
- struct intel_encoder *encoder);
-struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
-struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
- struct drm_crtc *crtc);
-enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
+
+extern void intel_connector_attach_encoder(struct intel_connector *connector,
+ struct intel_encoder *encoder);
+extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
+
+extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
+ struct drm_crtc *crtc);
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
- enum pipe pipe);
-void intel_wait_for_vblank(struct drm_device *dev, int pipe);
-void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
-int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
-void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port);
-bool intel_get_load_detect_pipe(struct drm_connector *connector,
- struct drm_display_mode *mode,
- struct intel_load_detect_pipe *old);
-void intel_release_load_detect_pipe(struct drm_connector *connector,
- struct intel_load_detect_pipe *old);
-int intel_pin_and_fence_fb_obj(struct drm_device *dev,
- struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined);
-void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
-int intel_framebuffer_init(struct drm_device *dev,
- struct intel_framebuffer *ifb,
- struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_i915_gem_object *obj);
-void intel_framebuffer_fini(struct intel_framebuffer *fb);
-void intel_prepare_page_flip(struct drm_device *dev, int plane);
-void intel_finish_page_flip(struct drm_device *dev, int pipe);
-void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
-struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
+extern enum transcoder
+intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
+ enum pipe pipe);
+extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
+extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
+extern int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
+extern void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port);
+
+struct intel_load_detect_pipe {
+ struct drm_framebuffer *release_fb;
+ bool load_detect_temp;
+ int dpms_mode;
+};
+extern bool intel_get_load_detect_pipe(struct drm_connector *connector,
+ struct drm_display_mode *mode,
+ struct intel_load_detect_pipe *old);
+extern void intel_release_load_detect_pipe(struct drm_connector *connector,
+ struct intel_load_detect_pipe *old);
+
+extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+ u16 blue, int regno);
+extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno);
+
+extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
+ struct drm_i915_gem_object *obj,
+ struct intel_ring_buffer *pipelined);
+extern void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
+
+extern int intel_framebuffer_init(struct drm_device *dev,
+ struct intel_framebuffer *ifb,
+ struct drm_mode_fb_cmd2 *mode_cmd,
+ struct drm_i915_gem_object *obj);
+extern void intel_framebuffer_fini(struct intel_framebuffer *fb);
+extern int intel_fbdev_init(struct drm_device *dev);
+extern void intel_fbdev_initial_config(struct drm_device *dev);
+extern void intel_fbdev_fini(struct drm_device *dev);
+extern void intel_fbdev_set_suspend(struct drm_device *dev, int state);
+extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
+extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
+extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
+
+extern void intel_setup_overlay(struct drm_device *dev);
+extern void intel_cleanup_overlay(struct drm_device *dev);
+extern int intel_overlay_switch_off(struct intel_overlay *overlay);
+extern int intel_overlay_put_image(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int intel_overlay_attrs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+extern void intel_fb_output_poll_changed(struct drm_device *dev);
+extern void intel_fb_restore_mode(struct drm_device *dev);
+
+struct intel_shared_dpll *
+intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
+
void assert_shared_dpll(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll,
bool state);
@@ -670,199 +696,104 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state);
#define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true)
#define assert_fdi_rx_pll_disabled(d, p) assert_fdi_rx_pll(d, p, false)
-void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state);
+extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
+ bool state);
#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
-void intel_write_eld(struct drm_encoder *encoder,
- struct drm_display_mode *mode);
-unsigned long intel_gen4_compute_page_offset(int *x, int *y,
- unsigned int tiling_mode,
- unsigned int bpp,
- unsigned int pitch);
-void intel_display_handle_reset(struct drm_device *dev);
-void hsw_enable_pc8_work(struct work_struct *__work);
-void hsw_enable_package_c8(struct drm_i915_private *dev_priv);
-void hsw_disable_package_c8(struct drm_i915_private *dev_priv);
-void intel_dp_get_m_n(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config);
-int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
-void
-ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
- int dotclock);
-bool intel_crtc_active(struct drm_crtc *crtc);
-void i915_disable_vga_mem(struct drm_device *dev);
-void hsw_enable_ips(struct intel_crtc *crtc);
-void hsw_disable_ips(struct intel_crtc *crtc);
-void intel_display_set_init_power(struct drm_device *dev, bool enable);
-
-
-/* intel_dp.c */
-void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
-bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
- struct intel_connector *intel_connector);
-void intel_dp_start_link_train(struct intel_dp *intel_dp);
-void intel_dp_complete_link_train(struct intel_dp *intel_dp);
-void intel_dp_stop_link_train(struct intel_dp *intel_dp);
-void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
-void intel_dp_encoder_destroy(struct drm_encoder *encoder);
-void intel_dp_check_link_status(struct intel_dp *intel_dp);
-bool intel_dp_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config);
-bool intel_dp_is_edp(struct drm_device *dev, enum port port);
-void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
-void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
-void ironlake_edp_panel_on(struct intel_dp *intel_dp);
-void ironlake_edp_panel_off(struct intel_dp *intel_dp);
-void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp);
-void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
-void intel_edp_psr_enable(struct intel_dp *intel_dp);
-void intel_edp_psr_disable(struct intel_dp *intel_dp);
-void intel_edp_psr_update(struct drm_device *dev);
-
-
-/* intel_dsi.c */
-bool intel_dsi_init(struct drm_device *dev);
-
-
-/* intel_dvo.c */
-void intel_dvo_init(struct drm_device *dev);
-
-
-/* legacy fbdev emulation in intel_fbdev.c */
-#ifdef CONFIG_DRM_I915_FBDEV
-extern int intel_fbdev_init(struct drm_device *dev);
-extern void intel_fbdev_initial_config(struct drm_device *dev);
-extern void intel_fbdev_fini(struct drm_device *dev);
-extern void intel_fbdev_set_suspend(struct drm_device *dev, int state);
-extern void intel_fbdev_output_poll_changed(struct drm_device *dev);
-extern void intel_fbdev_restore_mode(struct drm_device *dev);
-#else
-static inline int intel_fbdev_init(struct drm_device *dev)
-{
- return 0;
-}
-static inline void intel_fbdev_initial_config(struct drm_device *dev)
-{
-}
-
-static inline void intel_fbdev_fini(struct drm_device *dev)
-{
-}
-
-static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state)
-{
-}
-
-static inline void intel_fbdev_restore_mode(struct drm_device *dev)
-{
-}
-#endif
-
-/* intel_hdmi.c */
-void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port);
-void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
- struct intel_connector *intel_connector);
-struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
-bool intel_hdmi_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config);
-
-
-/* intel_lvds.c */
-void intel_lvds_init(struct drm_device *dev);
-bool intel_is_dual_link_lvds(struct drm_device *dev);
-
-
-/* intel_modes.c */
-int intel_connector_update_modes(struct drm_connector *connector,
- struct edid *edid);
-int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
-void intel_attach_force_audio_property(struct drm_connector *connector);
-void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
-
-
-/* intel_overlay.c */
-void intel_setup_overlay(struct drm_device *dev);
-void intel_cleanup_overlay(struct drm_device *dev);
-int intel_overlay_switch_off(struct intel_overlay *overlay);
-int intel_overlay_put_image(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-int intel_overlay_attrs(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-
-
-/* intel_panel.c */
-int intel_panel_init(struct intel_panel *panel,
- struct drm_display_mode *fixed_mode);
-void intel_panel_fini(struct intel_panel *panel);
-void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
- struct drm_display_mode *adjusted_mode);
-void intel_pch_panel_fitting(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config,
- int fitting_mode);
-void intel_gmch_panel_fitting(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config,
- int fitting_mode);
-void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
- u32 max);
-int intel_panel_setup_backlight(struct drm_connector *connector);
-void intel_panel_enable_backlight(struct intel_connector *connector);
-void intel_panel_disable_backlight(struct intel_connector *connector);
-void intel_panel_destroy_backlight(struct drm_device *dev);
-enum drm_connector_status intel_panel_detect(struct drm_device *dev);
-
-
-/* intel_pm.c */
-void intel_init_clock_gating(struct drm_device *dev);
-void intel_suspend_hw(struct drm_device *dev);
-void intel_update_watermarks(struct drm_crtc *crtc);
-void intel_update_sprite_watermarks(struct drm_plane *plane,
- struct drm_crtc *crtc,
- uint32_t sprite_width, int pixel_size,
- bool enabled, bool scaled);
-void intel_init_pm(struct drm_device *dev);
-bool intel_fbc_enabled(struct drm_device *dev);
-void intel_update_fbc(struct drm_device *dev);
-void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
-void intel_gpu_ips_teardown(void);
-int intel_power_domains_init(struct drm_device *dev);
-void intel_power_domains_remove(struct drm_device *dev);
-bool intel_display_power_enabled(struct drm_device *dev,
- enum intel_display_power_domain domain);
-void intel_display_power_get(struct drm_device *dev,
- enum intel_display_power_domain domain);
-void intel_display_power_put(struct drm_device *dev,
- enum intel_display_power_domain domain);
-void intel_power_domains_init_hw(struct drm_device *dev);
-void intel_set_power_well(struct drm_device *dev, bool enable);
-void intel_enable_gt_powersave(struct drm_device *dev);
-void intel_disable_gt_powersave(struct drm_device *dev);
-void ironlake_teardown_rc6(struct drm_device *dev);
+extern void intel_init_clock_gating(struct drm_device *dev);
+extern void intel_suspend_hw(struct drm_device *dev);
+extern void intel_write_eld(struct drm_encoder *encoder,
+ struct drm_display_mode *mode);
+extern void intel_prepare_ddi(struct drm_device *dev);
+extern void hsw_fdi_link_train(struct drm_crtc *crtc);
+extern void intel_ddi_init(struct drm_device *dev, enum port port);
+
+/* For use by IVB LP watermark workaround in intel_sprite.c */
+extern void intel_update_watermarks(struct drm_device *dev);
+extern void intel_update_sprite_watermarks(struct drm_plane *plane,
+ struct drm_crtc *crtc,
+ uint32_t sprite_width, int pixel_size,
+ bool enabled, bool scaled);
+
+extern unsigned long intel_gen4_compute_page_offset(int *x, int *y,
+ unsigned int tiling_mode,
+ unsigned int bpp,
+ unsigned int pitch);
+
+extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/* Power-related functions, located in intel_pm.c */
+extern void intel_init_pm(struct drm_device *dev);
+/* FBC */
+extern bool intel_fbc_enabled(struct drm_device *dev);
+extern void intel_update_fbc(struct drm_device *dev);
+/* IPS */
+extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
+extern void intel_gpu_ips_teardown(void);
+
+/* Power well */
+extern int i915_init_power_well(struct drm_device *dev);
+extern void i915_remove_power_well(struct drm_device *dev);
+
+extern bool intel_display_power_enabled(struct drm_device *dev,
+ enum intel_display_power_domain domain);
+extern void intel_init_power_well(struct drm_device *dev);
+extern void intel_set_power_well(struct drm_device *dev, bool enable);
+extern void intel_enable_gt_powersave(struct drm_device *dev);
+extern void intel_disable_gt_powersave(struct drm_device *dev);
+extern void ironlake_teardown_rc6(struct drm_device *dev);
void gen6_update_ring_freq(struct drm_device *dev);
-void gen6_rps_idle(struct drm_i915_private *dev_priv);
-void gen6_rps_boost(struct drm_i915_private *dev_priv);
-void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv);
-void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv);
-void ilk_wm_get_hw_state(struct drm_device *dev);
-
-
-/* intel_sdvo.c */
-bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
-
-
-/* intel_sprite.c */
-int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
-void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
- enum plane plane);
-void intel_plane_restore(struct drm_plane *plane);
-void intel_plane_disable(struct drm_plane *plane);
-int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-
-/* intel_tv.c */
-void intel_tv_init(struct drm_device *dev);
+extern bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe);
+extern int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv);
+extern void intel_ddi_pll_init(struct drm_device *dev);
+extern void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
+extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
+ enum transcoder cpu_transcoder);
+extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
+extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
+extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
+extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
+extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
+extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
+extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
+extern bool
+intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
+extern void intel_ddi_fdi_disable(struct drm_crtc *crtc);
+extern void intel_ddi_get_config(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config);
+
+extern void intel_display_handle_reset(struct drm_device *dev);
+extern bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
+ enum pipe pipe,
+ bool enable);
+extern bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
+ enum transcoder pch_transcoder,
+ bool enable);
+
+extern void intel_edp_psr_enable(struct intel_dp *intel_dp);
+extern void intel_edp_psr_disable(struct intel_dp *intel_dp);
+extern void intel_edp_psr_update(struct drm_device *dev);
+extern void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
+ bool switch_to_fclk, bool allow_power_down);
+extern void hsw_restore_lcpll(struct drm_i915_private *dev_priv);
+extern void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+extern void ilk_disable_gt_irq(struct drm_i915_private *dev_priv,
+ uint32_t mask);
+extern void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+extern void snb_disable_pm_irq(struct drm_i915_private *dev_priv,
+ uint32_t mask);
+extern void hsw_enable_pc8_work(struct work_struct *__work);
+extern void hsw_enable_package_c8(struct drm_i915_private *dev_priv);
+extern void hsw_disable_package_c8(struct drm_i915_private *dev_priv);
+extern void hsw_pc8_disable_interrupts(struct drm_device *dev);
+extern void hsw_pc8_restore_interrupts(struct drm_device *dev);
+extern void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv);
+extern void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv);
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
deleted file mode 100644
index d257b09..0000000
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Copyright © 2013 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Author: Jani Nikula <jani.nikula@intel.com>
- */
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-#include <drm/i915_drm.h>
-#include <linux/slab.h>
-#include "i915_drv.h"
-#include "intel_drv.h"
-#include "intel_dsi.h"
-#include "intel_dsi_cmd.h"
-
-/* the sub-encoders aka panel drivers */
-static const struct intel_dsi_device intel_dsi_devices[] = {
-};
-
-
-static void vlv_cck_modify(struct drm_i915_private *dev_priv, u32 reg, u32 val,
- u32 mask)
-{
- u32 tmp = vlv_cck_read(dev_priv, reg);
- tmp &= ~mask;
- tmp |= val;
- vlv_cck_write(dev_priv, reg, tmp);
-}
-
-static void band_gap_wa(struct drm_i915_private *dev_priv)
-{
- mutex_lock(&dev_priv->dpio_lock);
-
- /* Enable bandgap fix in GOP driver */
- vlv_cck_modify(dev_priv, 0x6D, 0x00010000, 0x00030000);
- msleep(20);
- vlv_cck_modify(dev_priv, 0x6E, 0x00010000, 0x00030000);
- msleep(20);
- vlv_cck_modify(dev_priv, 0x6F, 0x00010000, 0x00030000);
- msleep(20);
- vlv_cck_modify(dev_priv, 0x00, 0x00008000, 0x00008000);
- msleep(20);
- vlv_cck_modify(dev_priv, 0x00, 0x00000000, 0x00008000);
- msleep(20);
-
- /* Turn Display Trunk on */
- vlv_cck_modify(dev_priv, 0x6B, 0x00020000, 0x00030000);
- msleep(20);
-
- vlv_cck_modify(dev_priv, 0x6C, 0x00020000, 0x00030000);
- msleep(20);
-
- vlv_cck_modify(dev_priv, 0x6D, 0x00020000, 0x00030000);
- msleep(20);
- vlv_cck_modify(dev_priv, 0x6E, 0x00020000, 0x00030000);
- msleep(20);
- vlv_cck_modify(dev_priv, 0x6F, 0x00020000, 0x00030000);
-
- mutex_unlock(&dev_priv->dpio_lock);
-
- /* Need huge delay, otherwise clock is not stable */
- msleep(100);
-}
-
-static struct intel_dsi *intel_attached_dsi(struct drm_connector *connector)
-{
- return container_of(intel_attached_encoder(connector),
- struct intel_dsi, base);
-}
-
-static inline bool is_vid_mode(struct intel_dsi *intel_dsi)
-{
- return intel_dsi->dev.type == INTEL_DSI_VIDEO_MODE;
-}
-
-static inline bool is_cmd_mode(struct intel_dsi *intel_dsi)
-{
- return intel_dsi->dev.type == INTEL_DSI_COMMAND_MODE;
-}
-
-static void intel_dsi_hot_plug(struct intel_encoder *encoder)
-{
- DRM_DEBUG_KMS("\n");
-}
-
-static bool intel_dsi_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *config)
-{
- struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
- base);
- struct intel_connector *intel_connector = intel_dsi->attached_connector;
- struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
- struct drm_display_mode *adjusted_mode = &config->adjusted_mode;
- struct drm_display_mode *mode = &config->requested_mode;
-
- DRM_DEBUG_KMS("\n");
-
- if (fixed_mode)
- intel_fixed_panel_mode(fixed_mode, adjusted_mode);
-
- if (intel_dsi->dev.dev_ops->mode_fixup)
- return intel_dsi->dev.dev_ops->mode_fixup(&intel_dsi->dev,
- mode, adjusted_mode);
-
- return true;
-}
-
-static void intel_dsi_pre_pll_enable(struct intel_encoder *encoder)
-{
- DRM_DEBUG_KMS("\n");
-
- vlv_enable_dsi_pll(encoder);
-}
-
-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
-{
- DRM_DEBUG_KMS("\n");
-}
-
-static void intel_dsi_enable(struct intel_encoder *encoder)
-{
- struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
- struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
- int pipe = intel_crtc->pipe;
- u32 temp;
-
- DRM_DEBUG_KMS("\n");
-
- temp = I915_READ(MIPI_DEVICE_READY(pipe));
- if ((temp & DEVICE_READY) == 0) {
- temp &= ~ULPS_STATE_MASK;
- I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY);
- } else if (temp & ULPS_STATE_MASK) {
- temp &= ~ULPS_STATE_MASK;
- I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT);
- /*
- * We need to ensure that there is a minimum of 1 ms time
- * available before clearing the UPLS exit state.
- */
- msleep(2);
- I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
- }
-
- if (is_cmd_mode(intel_dsi))
- I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
-
- if (is_vid_mode(intel_dsi)) {
- msleep(20); /* XXX */
- dpi_send_cmd(intel_dsi, TURN_ON);
- msleep(100);
-
- /* assert ip_tg_enable signal */
- temp = I915_READ(MIPI_PORT_CTRL(pipe));
- I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE);
- POSTING_READ(MIPI_PORT_CTRL(pipe));
- }
-
- intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
-}
-
-static void intel_dsi_disable(struct intel_encoder *encoder)
-{
- struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
- struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
- int pipe = intel_crtc->pipe;
- u32 temp;
-
- DRM_DEBUG_KMS("\n");
-
- intel_dsi->dev.dev_ops->disable(&intel_dsi->dev);
-
- if (is_vid_mode(intel_dsi)) {
- dpi_send_cmd(intel_dsi, SHUTDOWN);
- msleep(10);
-
- /* de-assert ip_tg_enable signal */
- temp = I915_READ(MIPI_PORT_CTRL(pipe));
- I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE);
- POSTING_READ(MIPI_PORT_CTRL(pipe));
-
- msleep(2);
- }
-
- temp = I915_READ(MIPI_DEVICE_READY(pipe));
- if (temp & DEVICE_READY) {
- temp &= ~DEVICE_READY;
- temp &= ~ULPS_STATE_MASK;
- I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
- }
-}
-
-static void intel_dsi_post_disable(struct intel_encoder *encoder)
-{
- DRM_DEBUG_KMS("\n");
-
- vlv_disable_dsi_pll(encoder);
-}
-
-static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
- enum pipe *pipe)
-{
- struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- u32 port, func;
- enum pipe p;
-
- DRM_DEBUG_KMS("\n");
-
- /* XXX: this only works for one DSI output */
- for (p = PIPE_A; p <= PIPE_B; p++) {
- port = I915_READ(MIPI_PORT_CTRL(p));
- func = I915_READ(MIPI_DSI_FUNC_PRG(p));
-
- if ((port & DPI_ENABLE) || (func & CMD_MODE_DATA_WIDTH_MASK)) {
- if (I915_READ(MIPI_DEVICE_READY(p)) & DEVICE_READY) {
- *pipe = p;
- return true;
- }
- }
- }
-
- return false;
-}
-
-static void intel_dsi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
-{
- DRM_DEBUG_KMS("\n");
-
- /* XXX: read flags, set to adjusted_mode */
-}
-
-static int intel_dsi_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- struct intel_connector *intel_connector = to_intel_connector(connector);
- struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
- struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
-
- DRM_DEBUG_KMS("\n");
-
- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
- DRM_DEBUG_KMS("MODE_NO_DBLESCAN\n");
- return MODE_NO_DBLESCAN;
- }
-
- if (fixed_mode) {
- if (mode->hdisplay > fixed_mode->hdisplay)
- return MODE_PANEL;
- if (mode->vdisplay > fixed_mode->vdisplay)
- return MODE_PANEL;
- }
-
- return intel_dsi->dev.dev_ops->mode_valid(&intel_dsi->dev, mode);
-}
-
-/* return txclkesc cycles in terms of divider and duration in us */
-static u16 txclkesc(u32 divider, unsigned int us)
-{
- switch (divider) {
- case ESCAPE_CLOCK_DIVIDER_1:
- default:
- return 20 * us;
- case ESCAPE_CLOCK_DIVIDER_2:
- return 10 * us;
- case ESCAPE_CLOCK_DIVIDER_4:
- return 5 * us;
- }
-}
-
-/* return pixels in terms of txbyteclkhs */
-static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count)
-{
- return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp, 8), lane_count);
-}
-
-static void set_dsi_timings(struct drm_encoder *encoder,
- const struct drm_display_mode *mode)
-{
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
- int pipe = intel_crtc->pipe;
- unsigned int bpp = intel_crtc->config.pipe_bpp;
- unsigned int lane_count = intel_dsi->lane_count;
-
- u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp;
-
- hactive = mode->hdisplay;
- hfp = mode->hsync_start - mode->hdisplay;
- hsync = mode->hsync_end - mode->hsync_start;
- hbp = mode->htotal - mode->hsync_end;
-
- vfp = mode->vsync_start - mode->vdisplay;
- vsync = mode->vsync_end - mode->vsync_start;
- vbp = mode->vtotal - mode->vsync_end;
-
- /* horizontal values are in terms of high speed byte clock */
- hactive = txbyteclkhs(hactive, bpp, lane_count);
- hfp = txbyteclkhs(hfp, bpp, lane_count);
- hsync = txbyteclkhs(hsync, bpp, lane_count);
- hbp = txbyteclkhs(hbp, bpp, lane_count);
-
- I915_WRITE(MIPI_HACTIVE_AREA_COUNT(pipe), hactive);
- I915_WRITE(MIPI_HFP_COUNT(pipe), hfp);
-
- /* meaningful for video mode non-burst sync pulse mode only, can be zero
- * for non-burst sync events and burst modes */
- I915_WRITE(MIPI_HSYNC_PADDING_COUNT(pipe), hsync);
- I915_WRITE(MIPI_HBP_COUNT(pipe), hbp);
-
- /* vertical values are in terms of lines */
- I915_WRITE(MIPI_VFP_COUNT(pipe), vfp);
- I915_WRITE(MIPI_VSYNC_PADDING_COUNT(pipe), vsync);
- I915_WRITE(MIPI_VBP_COUNT(pipe), vbp);
-}
-
-static void intel_dsi_mode_set(struct intel_encoder *intel_encoder)
-{
- struct drm_encoder *encoder = &intel_encoder->base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
- struct drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
- int pipe = intel_crtc->pipe;
- unsigned int bpp = intel_crtc->config.pipe_bpp;
- u32 val, tmp;
-
- DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
-
- /* Update the DSI PLL */
- vlv_enable_dsi_pll(intel_encoder);
-
- /* XXX: Location of the call */
- band_gap_wa(dev_priv);
-
- /* escape clock divider, 20MHz, shared for A and C. device ready must be
- * off when doing this! txclkesc? */
- tmp = I915_READ(MIPI_CTRL(0));
- tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
- I915_WRITE(MIPI_CTRL(0), tmp | ESCAPE_CLOCK_DIVIDER_1);
-
- /* read request priority is per pipe */
- tmp = I915_READ(MIPI_CTRL(pipe));
- tmp &= ~READ_REQUEST_PRIORITY_MASK;
- I915_WRITE(MIPI_CTRL(pipe), tmp | READ_REQUEST_PRIORITY_HIGH);
-
- /* XXX: why here, why like this? handling in irq handler?! */
- I915_WRITE(MIPI_INTR_STAT(pipe), 0xffffffff);
- I915_WRITE(MIPI_INTR_EN(pipe), 0xffffffff);
-
- I915_WRITE(MIPI_DPHY_PARAM(pipe),
- 0x3c << EXIT_ZERO_COUNT_SHIFT |
- 0x1f << TRAIL_COUNT_SHIFT |
- 0xc5 << CLK_ZERO_COUNT_SHIFT |
- 0x1f << PREPARE_COUNT_SHIFT);
-
- I915_WRITE(MIPI_DPI_RESOLUTION(pipe),
- adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT |
- adjusted_mode->hdisplay << HORIZONTAL_ADDRESS_SHIFT);
-
- set_dsi_timings(encoder, adjusted_mode);
-
- val = intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT;
- if (is_cmd_mode(intel_dsi)) {
- val |= intel_dsi->channel << CMD_MODE_CHANNEL_NUMBER_SHIFT;
- val |= CMD_MODE_DATA_WIDTH_8_BIT; /* XXX */
- } else {
- val |= intel_dsi->channel << VID_MODE_CHANNEL_NUMBER_SHIFT;
-
- /* XXX: cross-check bpp vs. pixel format? */
- val |= intel_dsi->pixel_format;
- }
- I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), val);
-
- /* timeouts for recovery. one frame IIUC. if counter expires, EOT and
- * stop state. */
-
- /*
- * In burst mode, value greater than one DPI line Time in byte clock
- * (txbyteclkhs) To timeout this timer 1+ of the above said value is
- * recommended.
- *
- * In non-burst mode, Value greater than one DPI frame time in byte
- * clock(txbyteclkhs) To timeout this timer 1+ of the above said value
- * is recommended.
- *
- * In DBI only mode, value greater than one DBI frame time in byte
- * clock(txbyteclkhs) To timeout this timer 1+ of the above said value
- * is recommended.
- */
-
- if (is_vid_mode(intel_dsi) &&
- intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
- I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
- txbyteclkhs(adjusted_mode->htotal, bpp,
- intel_dsi->lane_count) + 1);
- } else {
- I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
- txbyteclkhs(adjusted_mode->vtotal *
- adjusted_mode->htotal,
- bpp, intel_dsi->lane_count) + 1);
- }
- I915_WRITE(MIPI_LP_RX_TIMEOUT(pipe), 8309); /* max */
- I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), 0x14); /* max */
- I915_WRITE(MIPI_DEVICE_RESET_TIMER(pipe), 0xffff); /* max */
-
- /* dphy stuff */
-
- /* in terms of low power clock */
- I915_WRITE(MIPI_INIT_COUNT(pipe), txclkesc(ESCAPE_CLOCK_DIVIDER_1, 100));
-
- /* recovery disables */
- I915_WRITE(MIPI_EOT_DISABLE(pipe), intel_dsi->eot_disable);
-
- /* in terms of txbyteclkhs. actual high to low switch +
- * MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK.
- *
- * XXX: write MIPI_STOP_STATE_STALL?
- */
- I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(pipe), 0x46);
-
- /* XXX: low power clock equivalence in terms of byte clock. the number
- * of byte clocks occupied in one low power clock. based on txbyteclkhs
- * and txclkesc. txclkesc time / txbyteclk time * (105 +
- * MIPI_STOP_STATE_STALL) / 105.???
- */
- I915_WRITE(MIPI_LP_BYTECLK(pipe), 4);
-
- /* the bw essential for transmitting 16 long packets containing 252
- * bytes meant for dcs write memory command is programmed in this
- * register in terms of byte clocks. based on dsi transfer rate and the
- * number of lanes configured the time taken to transmit 16 long packets
- * in a dsi stream varies. */
- I915_WRITE(MIPI_DBI_BW_CTRL(pipe), 0x820);
-
- I915_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe),
- 0xa << LP_HS_SSW_CNT_SHIFT |
- 0x14 << HS_LP_PWR_SW_CNT_SHIFT);
-
- if (is_vid_mode(intel_dsi))
- I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe),
- intel_dsi->video_mode_format);
-}
-
-static enum drm_connector_status
-intel_dsi_detect(struct drm_connector *connector, bool force)
-{
- struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
- DRM_DEBUG_KMS("\n");
- return intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
-}
-
-static int intel_dsi_get_modes(struct drm_connector *connector)
-{
- struct intel_connector *intel_connector = to_intel_connector(connector);
- struct drm_display_mode *mode;
-
- DRM_DEBUG_KMS("\n");
-
- if (!intel_connector->panel.fixed_mode) {
- DRM_DEBUG_KMS("no fixed mode\n");
- return 0;
- }
-
- mode = drm_mode_duplicate(connector->dev,
- intel_connector->panel.fixed_mode);
- if (!mode) {
- DRM_DEBUG_KMS("drm_mode_duplicate failed\n");
- return 0;
- }
-
- drm_mode_probed_add(connector, mode);
- return 1;
-}
-
-static void intel_dsi_destroy(struct drm_connector *connector)
-{
- struct intel_connector *intel_connector = to_intel_connector(connector);
-
- DRM_DEBUG_KMS("\n");
- intel_panel_fini(&intel_connector->panel);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
-
-static const struct drm_encoder_funcs intel_dsi_funcs = {
- .destroy = intel_encoder_destroy,
-};
-
-static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = {
- .get_modes = intel_dsi_get_modes,
- .mode_valid = intel_dsi_mode_valid,
- .best_encoder = intel_best_encoder,
-};
-
-static const struct drm_connector_funcs intel_dsi_connector_funcs = {
- .dpms = intel_connector_dpms,
- .detect = intel_dsi_detect,
- .destroy = intel_dsi_destroy,
- .fill_modes = drm_helper_probe_single_connector_modes,
-};
-
-bool intel_dsi_init(struct drm_device *dev)
-{
- struct intel_dsi *intel_dsi;
- struct intel_encoder *intel_encoder;
- struct drm_encoder *encoder;
- struct intel_connector *intel_connector;
- struct drm_connector *connector;
- struct drm_display_mode *fixed_mode = NULL;
- const struct intel_dsi_device *dsi;
- unsigned int i;
-
- DRM_DEBUG_KMS("\n");
-
- intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
- if (!intel_dsi)
- return false;
-
- intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
- if (!intel_connector) {
- kfree(intel_dsi);
- return false;
- }
-
- intel_encoder = &intel_dsi->base;
- encoder = &intel_encoder->base;
- intel_dsi->attached_connector = intel_connector;
-
- connector = &intel_connector->base;
-
- drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI);
-
- /* XXX: very likely not all of these are needed */
- intel_encoder->hot_plug = intel_dsi_hot_plug;
- intel_encoder->compute_config = intel_dsi_compute_config;
- intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable;
- intel_encoder->pre_enable = intel_dsi_pre_enable;
- intel_encoder->enable = intel_dsi_enable;
- intel_encoder->mode_set = intel_dsi_mode_set;
- intel_encoder->disable = intel_dsi_disable;
- intel_encoder->post_disable = intel_dsi_post_disable;
- intel_encoder->get_hw_state = intel_dsi_get_hw_state;
- intel_encoder->get_config = intel_dsi_get_config;
-
- intel_connector->get_hw_state = intel_connector_get_hw_state;
-
- for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) {
- dsi = &intel_dsi_devices[i];
- intel_dsi->dev = *dsi;
-
- if (dsi->dev_ops->init(&intel_dsi->dev))
- break;
- }
-
- if (i == ARRAY_SIZE(intel_dsi_devices)) {
- DRM_DEBUG_KMS("no device found\n");
- goto err;
- }
-
- intel_encoder->type = INTEL_OUTPUT_DSI;
- intel_encoder->crtc_mask = (1 << 0); /* XXX */
-
- intel_encoder->cloneable = false;
- drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
- DRM_MODE_CONNECTOR_DSI);
-
- drm_connector_helper_add(connector, &intel_dsi_connector_helper_funcs);
-
- connector->display_info.subpixel_order = SubPixelHorizontalRGB; /*XXX*/
- connector->interlace_allowed = false;
- connector->doublescan_allowed = false;
-
- intel_connector_attach_encoder(intel_connector, intel_encoder);
-
- drm_sysfs_connector_add(connector);
-
- fixed_mode = dsi->dev_ops->get_modes(&intel_dsi->dev);
- if (!fixed_mode) {
- DRM_DEBUG_KMS("no fixed mode\n");
- goto err;
- }
-
- fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
- intel_panel_init(&intel_connector->panel, fixed_mode);
-
- return true;
-
-err:
- drm_encoder_cleanup(&intel_encoder->base);
- kfree(intel_dsi);
- kfree(intel_connector);
-
- return false;
-}
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
deleted file mode 100644
index c7765f3..0000000
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright © 2013 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- */
-
-#ifndef _INTEL_DSI_H
-#define _INTEL_DSI_H
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include "intel_drv.h"
-
-struct intel_dsi_device {
- unsigned int panel_id;
- const char *name;
- int type;
- const struct intel_dsi_dev_ops *dev_ops;
- void *dev_priv;
-};
-
-struct intel_dsi_dev_ops {
- bool (*init)(struct intel_dsi_device *dsi);
-
- /* This callback must be able to assume DSI commands can be sent */
- void (*enable)(struct intel_dsi_device *dsi);
-
- /* This callback must be able to assume DSI commands can be sent */
- void (*disable)(struct intel_dsi_device *dsi);
-
- int (*mode_valid)(struct intel_dsi_device *dsi,
- struct drm_display_mode *mode);
-
- bool (*mode_fixup)(struct intel_dsi_device *dsi,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-
- void (*mode_set)(struct intel_dsi_device *dsi,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-
- enum drm_connector_status (*detect)(struct intel_dsi_device *dsi);
-
- bool (*get_hw_state)(struct intel_dsi_device *dev);
-
- struct drm_display_mode *(*get_modes)(struct intel_dsi_device *dsi);
-
- void (*destroy) (struct intel_dsi_device *dsi);
-};
-
-struct intel_dsi {
- struct intel_encoder base;
-
- struct intel_dsi_device dev;
-
- struct intel_connector *attached_connector;
-
- /* if true, use HS mode, otherwise LP */
- bool hs;
-
- /* virtual channel */
- int channel;
-
- /* number of DSI lanes */
- unsigned int lane_count;
-
- /* video mode pixel format for MIPI_DSI_FUNC_PRG register */
- u32 pixel_format;
-
- /* video mode format for MIPI_VIDEO_MODE_FORMAT register */
- u32 video_mode_format;
-
- /* eot for MIPI_EOT_DISABLE register */
- u32 eot_disable;
-};
-
-static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
-{
- return container_of(encoder, struct intel_dsi, base.base);
-}
-
-extern void vlv_enable_dsi_pll(struct intel_encoder *encoder);
-extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
-
-#endif /* _INTEL_DSI_H */
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c
deleted file mode 100644
index 7c40f98..0000000
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright © 2013 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Author: Jani Nikula <jani.nikula@intel.com>
- */
-
-#include <linux/export.h>
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <video/mipi_display.h>
-#include "i915_drv.h"
-#include "intel_drv.h"
-#include "intel_dsi.h"
-#include "intel_dsi_cmd.h"
-
-/*
- * XXX: MIPI_DATA_ADDRESS, MIPI_DATA_LENGTH, MIPI_COMMAND_LENGTH, and
- * MIPI_COMMAND_ADDRESS registers.
- *
- * Apparently these registers provide a MIPI adapter level way to send (lots of)
- * commands and data to the receiver, without having to write the commands and
- * data to MIPI_{HS,LP}_GEN_{CTRL,DATA} registers word by word.
- *
- * Presumably for anything other than MIPI_DCS_WRITE_MEMORY_START and
- * MIPI_DCS_WRITE_MEMORY_CONTINUE (which are used to update the external
- * framebuffer in command mode displays) these are just an optimization that can
- * come later.
- *
- * For memory writes, these should probably be used for performance.
- */
-
-static void print_stat(struct intel_dsi *intel_dsi)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 val;
-
- val = I915_READ(MIPI_INTR_STAT(pipe));
-
-#define STAT_BIT(val, bit) (val) & (bit) ? " " #bit : ""
- DRM_DEBUG_KMS("MIPI_INTR_STAT(%d) = %08x"
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
- "\n", pipe, val,
- STAT_BIT(val, TEARING_EFFECT),
- STAT_BIT(val, SPL_PKT_SENT_INTERRUPT),
- STAT_BIT(val, GEN_READ_DATA_AVAIL),
- STAT_BIT(val, LP_GENERIC_WR_FIFO_FULL),
- STAT_BIT(val, HS_GENERIC_WR_FIFO_FULL),
- STAT_BIT(val, RX_PROT_VIOLATION),
- STAT_BIT(val, RX_INVALID_TX_LENGTH),
- STAT_BIT(val, ACK_WITH_NO_ERROR),
- STAT_BIT(val, TURN_AROUND_ACK_TIMEOUT),
- STAT_BIT(val, LP_RX_TIMEOUT),
- STAT_BIT(val, HS_TX_TIMEOUT),
- STAT_BIT(val, DPI_FIFO_UNDERRUN),
- STAT_BIT(val, LOW_CONTENTION),
- STAT_BIT(val, HIGH_CONTENTION),
- STAT_BIT(val, TXDSI_VC_ID_INVALID),
- STAT_BIT(val, TXDSI_DATA_TYPE_NOT_RECOGNISED),
- STAT_BIT(val, TXCHECKSUM_ERROR),
- STAT_BIT(val, TXECC_MULTIBIT_ERROR),
- STAT_BIT(val, TXECC_SINGLE_BIT_ERROR),
- STAT_BIT(val, TXFALSE_CONTROL_ERROR),
- STAT_BIT(val, RXDSI_VC_ID_INVALID),
- STAT_BIT(val, RXDSI_DATA_TYPE_NOT_REGOGNISED),
- STAT_BIT(val, RXCHECKSUM_ERROR),
- STAT_BIT(val, RXECC_MULTIBIT_ERROR),
- STAT_BIT(val, RXECC_SINGLE_BIT_ERROR),
- STAT_BIT(val, RXFALSE_CONTROL_ERROR),
- STAT_BIT(val, RXHS_RECEIVE_TIMEOUT_ERROR),
- STAT_BIT(val, RX_LP_TX_SYNC_ERROR),
- STAT_BIT(val, RXEXCAPE_MODE_ENTRY_ERROR),
- STAT_BIT(val, RXEOT_SYNC_ERROR),
- STAT_BIT(val, RXSOT_SYNC_ERROR),
- STAT_BIT(val, RXSOT_ERROR));
-#undef STAT_BIT
-}
-
-enum dsi_type {
- DSI_DCS,
- DSI_GENERIC,
-};
-
-/* enable or disable command mode hs transmissions */
-void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 temp;
- u32 mask = DBI_FIFO_EMPTY;
-
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
-
- temp = I915_READ(MIPI_HS_LP_DBI_ENABLE(pipe));
- temp &= DBI_HS_LP_MODE_MASK;
- I915_WRITE(MIPI_HS_LP_DBI_ENABLE(pipe), enable ? DBI_HS_MODE : DBI_LP_MODE);
-
- intel_dsi->hs = enable;
-}
-
-static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel,
- u8 data_type, u16 data)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 ctrl_reg;
- u32 ctrl;
- u32 mask;
-
- DRM_DEBUG_KMS("channel %d, data_type %d, data %04x\n",
- channel, data_type, data);
-
- if (intel_dsi->hs) {
- ctrl_reg = MIPI_HS_GEN_CTRL(pipe);
- mask = HS_CTRL_FIFO_FULL;
- } else {
- ctrl_reg = MIPI_LP_GEN_CTRL(pipe);
- mask = LP_CTRL_FIFO_FULL;
- }
-
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50)) {
- DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n");
- print_stat(intel_dsi);
- }
-
- /*
- * Note: This function is also used for long packets, with length passed
- * as data, since SHORT_PACKET_PARAM_SHIFT ==
- * LONG_PACKET_WORD_COUNT_SHIFT.
- */
- ctrl = data << SHORT_PACKET_PARAM_SHIFT |
- channel << VIRTUAL_CHANNEL_SHIFT |
- data_type << DATA_TYPE_SHIFT;
-
- I915_WRITE(ctrl_reg, ctrl);
-
- return 0;
-}
-
-static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel,
- u8 data_type, const u8 *data, int len)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 data_reg;
- int i, j, n;
- u32 mask;
-
- DRM_DEBUG_KMS("channel %d, data_type %d, len %04x\n",
- channel, data_type, len);
-
- if (intel_dsi->hs) {
- data_reg = MIPI_HS_GEN_DATA(pipe);
- mask = HS_DATA_FIFO_FULL;
- } else {
- data_reg = MIPI_LP_GEN_DATA(pipe);
- mask = LP_DATA_FIFO_FULL;
- }
-
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50))
- DRM_ERROR("Timeout waiting for HS/LP DATA FIFO !full\n");
-
- for (i = 0; i < len; i += n) {
- u32 val = 0;
- n = min_t(int, len - i, 4);
-
- for (j = 0; j < n; j++)
- val |= *data++ << 8 * j;
-
- I915_WRITE(data_reg, val);
- /* XXX: check for data fifo full, once that is set, write 4
- * dwords, then wait for not set, then continue. */
- }
-
- return dsi_vc_send_short(intel_dsi, channel, data_type, len);
-}
-
-static int dsi_vc_write_common(struct intel_dsi *intel_dsi,
- int channel, const u8 *data, int len,
- enum dsi_type type)
-{
- int ret;
-
- if (len == 0) {
- BUG_ON(type == DSI_GENERIC);
- ret = dsi_vc_send_short(intel_dsi, channel,
- MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM,
- 0);
- } else if (len == 1) {
- ret = dsi_vc_send_short(intel_dsi, channel,
- type == DSI_GENERIC ?
- MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM :
- MIPI_DSI_DCS_SHORT_WRITE, data[0]);
- } else if (len == 2) {
- ret = dsi_vc_send_short(intel_dsi, channel,
- type == DSI_GENERIC ?
- MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM :
- MIPI_DSI_DCS_SHORT_WRITE_PARAM,
- (data[1] << 8) | data[0]);
- } else {
- ret = dsi_vc_send_long(intel_dsi, channel,
- type == DSI_GENERIC ?
- MIPI_DSI_GENERIC_LONG_WRITE :
- MIPI_DSI_DCS_LONG_WRITE, data, len);
- }
-
- return ret;
-}
-
-int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len)
-{
- return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_DCS);
-}
-
-int dsi_vc_generic_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len)
-{
- return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_GENERIC);
-}
-
-static int dsi_vc_dcs_send_read_request(struct intel_dsi *intel_dsi,
- int channel, u8 dcs_cmd)
-{
- return dsi_vc_send_short(intel_dsi, channel, MIPI_DSI_DCS_READ,
- dcs_cmd);
-}
-
-static int dsi_vc_generic_send_read_request(struct intel_dsi *intel_dsi,
- int channel, u8 *reqdata,
- int reqlen)
-{
- u16 data;
- u8 data_type;
-
- switch (reqlen) {
- case 0:
- data_type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
- data = 0;
- break;
- case 1:
- data_type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
- data = reqdata[0];
- break;
- case 2:
- data_type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
- data = (reqdata[1] << 8) | reqdata[0];
- break;
- default:
- BUG();
- }
-
- return dsi_vc_send_short(intel_dsi, channel, data_type, data);
-}
-
-static int dsi_read_data_return(struct intel_dsi *intel_dsi,
- u8 *buf, int buflen)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- int i, len = 0;
- u32 data_reg, val;
-
- if (intel_dsi->hs) {
- data_reg = MIPI_HS_GEN_DATA(pipe);
- } else {
- data_reg = MIPI_LP_GEN_DATA(pipe);
- }
-
- while (len < buflen) {
- val = I915_READ(data_reg);
- for (i = 0; i < 4 && len < buflen; i++, len++)
- buf[len] = val >> 8 * i;
- }
-
- return len;
-}
-
-int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
- u8 *buf, int buflen)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 mask;
- int ret;
-
- /*
- * XXX: should issue multiple read requests and reads if request is
- * longer than MIPI_MAX_RETURN_PKT_SIZE
- */
-
- I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL);
-
- ret = dsi_vc_dcs_send_read_request(intel_dsi, channel, dcs_cmd);
- if (ret)
- return ret;
-
- mask = GEN_READ_DATA_AVAIL;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for read data.\n");
-
- ret = dsi_read_data_return(intel_dsi, buf, buflen);
- if (ret < 0)
- return ret;
-
- if (ret != buflen)
- return -EIO;
-
- return 0;
-}
-
-int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
- u8 *reqdata, int reqlen, u8 *buf, int buflen)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 mask;
- int ret;
-
- /*
- * XXX: should issue multiple read requests and reads if request is
- * longer than MIPI_MAX_RETURN_PKT_SIZE
- */
-
- I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL);
-
- ret = dsi_vc_generic_send_read_request(intel_dsi, channel, reqdata,
- reqlen);
- if (ret)
- return ret;
-
- mask = GEN_READ_DATA_AVAIL;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for read data.\n");
-
- ret = dsi_read_data_return(intel_dsi, buf, buflen);
- if (ret < 0)
- return ret;
-
- if (ret != buflen)
- return -EIO;
-
- return 0;
-}
-
-/*
- * send a video mode command
- *
- * XXX: commands with data in MIPI_DPI_DATA?
- */
-int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 mask;
-
- /* XXX: pipe, hs */
- if (intel_dsi->hs)
- cmd &= ~DPI_LP_MODE;
- else
- cmd |= DPI_LP_MODE;
-
- /* DPI virtual channel?! */
-
- mask = DPI_FIFO_EMPTY;
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for DPI FIFO empty.\n");
-
- /* clear bit */
- I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT);
-
- /* XXX: old code skips write if control unchanged */
- if (cmd == I915_READ(MIPI_DPI_CONTROL(pipe)))
- DRM_ERROR("Same special packet %02x twice in a row.\n", cmd);
-
- I915_WRITE(MIPI_DPI_CONTROL(pipe), cmd);
-
- mask = SPL_PKT_SENT_INTERRUPT;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 100))
- DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.h b/drivers/gpu/drm/i915/intel_dsi_cmd.h
deleted file mode 100644
index 54c8a23..0000000
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright © 2013 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Author: Jani Nikula <jani.nikula@intel.com>
- */
-
-#ifndef _INTEL_DSI_DSI_H
-#define _INTEL_DSI_DSI_H
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <video/mipi_display.h>
-#include "i915_drv.h"
-#include "intel_drv.h"
-#include "intel_dsi.h"
-
-void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable);
-
-int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len);
-
-int dsi_vc_generic_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len);
-
-int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
- u8 *buf, int buflen);
-
-int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
- u8 *reqdata, int reqlen, u8 *buf, int buflen);
-
-int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd);
-
-/* XXX: questionable write helpers */
-static inline int dsi_vc_dcs_write_0(struct intel_dsi *intel_dsi,
- int channel, u8 dcs_cmd)
-{
- return dsi_vc_dcs_write(intel_dsi, channel, &dcs_cmd, 1);
-}
-
-static inline int dsi_vc_dcs_write_1(struct intel_dsi *intel_dsi,
- int channel, u8 dcs_cmd, u8 param)
-{
- u8 buf[2] = { dcs_cmd, param };
- return dsi_vc_dcs_write(intel_dsi, channel, buf, 2);
-}
-
-static inline int dsi_vc_generic_write_0(struct intel_dsi *intel_dsi,
- int channel)
-{
- return dsi_vc_generic_write(intel_dsi, channel, NULL, 0);
-}
-
-static inline int dsi_vc_generic_write_1(struct intel_dsi *intel_dsi,
- int channel, u8 param)
-{
- return dsi_vc_generic_write(intel_dsi, channel, &param, 1);
-}
-
-static inline int dsi_vc_generic_write_2(struct intel_dsi *intel_dsi,
- int channel, u8 param1, u8 param2)
-{
- u8 buf[2] = { param1, param2 };
- return dsi_vc_generic_write(intel_dsi, channel, buf, 2);
-}
-
-/* XXX: questionable read helpers */
-static inline int dsi_vc_generic_read_0(struct intel_dsi *intel_dsi,
- int channel, u8 *buf, int buflen)
-{
- return dsi_vc_generic_read(intel_dsi, channel, NULL, 0, buf, buflen);
-}
-
-static inline int dsi_vc_generic_read_1(struct intel_dsi *intel_dsi,
- int channel, u8 param, u8 *buf,
- int buflen)
-{
- return dsi_vc_generic_read(intel_dsi, channel, &param, 1, buf, buflen);
-}
-
-static inline int dsi_vc_generic_read_2(struct intel_dsi *intel_dsi,
- int channel, u8 param1, u8 param2,
- u8 *buf, int buflen)
-{
- u8 req[2] = { param1, param2 };
-
- return dsi_vc_generic_read(intel_dsi, channel, req, 2, buf, buflen);
-}
-
-
-#endif /* _INTEL_DSI_DSI_H */
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
deleted file mode 100644
index 44279b2..0000000
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright © 2013 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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:
- * Shobhit Kumar <shobhit.kumar@intel.com>
- * Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
- */
-
-#include <linux/kernel.h>
-#include "intel_drv.h"
-#include "i915_drv.h"
-#include "intel_dsi.h"
-
-#define DSI_HSS_PACKET_SIZE 4
-#define DSI_HSE_PACKET_SIZE 4
-#define DSI_HSA_PACKET_EXTRA_SIZE 6
-#define DSI_HBP_PACKET_EXTRA_SIZE 6
-#define DSI_HACTIVE_PACKET_EXTRA_SIZE 6
-#define DSI_HFP_PACKET_EXTRA_SIZE 6
-#define DSI_EOTP_PACKET_SIZE 4
-
-struct dsi_mnp {
- u32 dsi_pll_ctrl;
- u32 dsi_pll_div;
-};
-
-static const u32 lfsr_converts[] = {
- 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 62 - 70 */
- 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
- 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
- 71, 35 /* 91 - 92 */
-};
-
-static u32 dsi_rr_formula(const struct drm_display_mode *mode,
- int pixel_format, int video_mode_format,
- int lane_count, bool eotp)
-{
- u32 bpp;
- u32 hactive, vactive, hfp, hsync, hbp, vfp, vsync, vbp;
- u32 hsync_bytes, hbp_bytes, hactive_bytes, hfp_bytes;
- u32 bytes_per_line, bytes_per_frame;
- u32 num_frames;
- u32 bytes_per_x_frames, bytes_per_x_frames_x_lanes;
- u32 dsi_bit_clock_hz;
- u32 dsi_clk;
-
- switch (pixel_format) {
- default:
- case VID_MODE_FORMAT_RGB888:
- case VID_MODE_FORMAT_RGB666_LOOSE:
- bpp = 24;
- break;
- case VID_MODE_FORMAT_RGB666:
- bpp = 18;
- break;
- case VID_MODE_FORMAT_RGB565:
- bpp = 16;
- break;
- }
-
- hactive = mode->hdisplay;
- vactive = mode->vdisplay;
- hfp = mode->hsync_start - mode->hdisplay;
- hsync = mode->hsync_end - mode->hsync_start;
- hbp = mode->htotal - mode->hsync_end;
-
- vfp = mode->vsync_start - mode->vdisplay;
- vsync = mode->vsync_end - mode->vsync_start;
- vbp = mode->vtotal - mode->vsync_end;
-
- hsync_bytes = DIV_ROUND_UP(hsync * bpp, 8);
- hbp_bytes = DIV_ROUND_UP(hbp * bpp, 8);
- hactive_bytes = DIV_ROUND_UP(hactive * bpp, 8);
- hfp_bytes = DIV_ROUND_UP(hfp * bpp, 8);
-
- bytes_per_line = DSI_HSS_PACKET_SIZE + hsync_bytes +
- DSI_HSA_PACKET_EXTRA_SIZE + DSI_HSE_PACKET_SIZE +
- hbp_bytes + DSI_HBP_PACKET_EXTRA_SIZE +
- hactive_bytes + DSI_HACTIVE_PACKET_EXTRA_SIZE +
- hfp_bytes + DSI_HFP_PACKET_EXTRA_SIZE;
-
- /*
- * XXX: Need to accurately calculate LP to HS transition timeout and add
- * it to bytes_per_line/bytes_per_frame.
- */
-
- if (eotp && video_mode_format == VIDEO_MODE_BURST)
- bytes_per_line += DSI_EOTP_PACKET_SIZE;
-
- bytes_per_frame = vsync * bytes_per_line + vbp * bytes_per_line +
- vactive * bytes_per_line + vfp * bytes_per_line;
-
- if (eotp &&
- (video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE ||
- video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS))
- bytes_per_frame += DSI_EOTP_PACKET_SIZE;
-
- num_frames = drm_mode_vrefresh(mode);
- bytes_per_x_frames = num_frames * bytes_per_frame;
-
- bytes_per_x_frames_x_lanes = bytes_per_x_frames / lane_count;
-
- /* the dsi clock is divided by 2 in the hardware to get dsi ddr clock */
- dsi_bit_clock_hz = bytes_per_x_frames_x_lanes * 8;
- dsi_clk = dsi_bit_clock_hz / (1000 * 1000);
-
- if (eotp && video_mode_format == VIDEO_MODE_BURST)
- dsi_clk *= 2;
-
- return dsi_clk;
-}
-
-#ifdef MNP_FROM_TABLE
-
-struct dsi_clock_table {
- u32 freq;
- u8 m;
- u8 p;
-};
-
-static const struct dsi_clock_table dsi_clk_tbl[] = {
- {300, 72, 6}, {313, 75, 6}, {323, 78, 6}, {333, 80, 6},
- {343, 82, 6}, {353, 85, 6}, {363, 87, 6}, {373, 90, 6},
- {383, 92, 6}, {390, 78, 5}, {393, 79, 5}, {400, 80, 5},
- {401, 80, 5}, {402, 80, 5}, {403, 81, 5}, {404, 81, 5},
- {405, 81, 5}, {406, 81, 5}, {407, 81, 5}, {408, 82, 5},
- {409, 82, 5}, {410, 82, 5}, {411, 82, 5}, {412, 82, 5},
- {413, 83, 5}, {414, 83, 5}, {415, 83, 5}, {416, 83, 5},
- {417, 83, 5}, {418, 84, 5}, {419, 84, 5}, {420, 84, 5},
- {430, 86, 5}, {440, 88, 5}, {450, 90, 5}, {460, 92, 5},
- {470, 75, 4}, {480, 77, 4}, {490, 78, 4}, {500, 80, 4},
- {510, 82, 4}, {520, 83, 4}, {530, 85, 4}, {540, 86, 4},
- {550, 88, 4}, {560, 90, 4}, {570, 91, 4}, {580, 70, 3},
- {590, 71, 3}, {600, 72, 3}, {610, 73, 3}, {620, 74, 3},
- {630, 76, 3}, {640, 77, 3}, {650, 78, 3}, {660, 79, 3},
- {670, 80, 3}, {680, 82, 3}, {690, 83, 3}, {700, 84, 3},
- {710, 85, 3}, {720, 86, 3}, {730, 88, 3}, {740, 89, 3},
- {750, 90, 3}, {760, 91, 3}, {770, 92, 3}, {780, 62, 2},
- {790, 63, 2}, {800, 64, 2}, {880, 70, 2}, {900, 72, 2},
- {1000, 80, 2}, /* dsi clock frequency in Mhz*/
-};
-
-static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp)
-{
- unsigned int i;
- u8 m;
- u8 n;
- u8 p;
- u32 m_seed;
-
- if (dsi_clk < 300 || dsi_clk > 1000)
- return -ECHRNG;
-
- for (i = 0; i <= ARRAY_SIZE(dsi_clk_tbl); i++) {
- if (dsi_clk_tbl[i].freq > dsi_clk)
- break;
- }
-
- m = dsi_clk_tbl[i].m;
- p = dsi_clk_tbl[i].p;
- m_seed = lfsr_converts[m - 62];
- n = 1;
- dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + p - 2);
- dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT |
- m_seed << DSI_PLL_M1_DIV_SHIFT;
-
- return 0;
-}
-
-#else
-
-static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp)
-{
- u32 m, n, p;
- u32 ref_clk;
- u32 error;
- u32 tmp_error;
- u32 target_dsi_clk;
- u32 calc_dsi_clk;
- u32 calc_m;
- u32 calc_p;
- u32 m_seed;
-
- if (dsi_clk < 300 || dsi_clk > 1150) {
- DRM_ERROR("DSI CLK Out of Range\n");
- return -ECHRNG;
- }
-
- ref_clk = 25000;
- target_dsi_clk = dsi_clk * 1000;
- error = 0xFFFFFFFF;
- calc_m = 0;
- calc_p = 0;
-
- for (m = 62; m <= 92; m++) {
- for (p = 2; p <= 6; p++) {
-
- calc_dsi_clk = (m * ref_clk) / p;
- if (calc_dsi_clk >= target_dsi_clk) {
- tmp_error = calc_dsi_clk - target_dsi_clk;
- if (tmp_error < error) {
- error = tmp_error;
- calc_m = m;
- calc_p = p;
- }
- }
- }
- }
-
- m_seed = lfsr_converts[calc_m - 62];
- n = 1;
- dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
- dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT |
- m_seed << DSI_PLL_M1_DIV_SHIFT;
-
- return 0;
-}
-
-#endif
-
-/*
- * XXX: The muxing and gating is hard coded for now. Need to add support for
- * sharing PLLs with two DSI outputs.
- */
-static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
-{
- struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
- const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
- struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
- int ret;
- struct dsi_mnp dsi_mnp;
- u32 dsi_clk;
-
- dsi_clk = dsi_rr_formula(mode, intel_dsi->pixel_format,
- intel_dsi->video_mode_format,
- intel_dsi->lane_count, !intel_dsi->eot_disable);
-
- ret = dsi_calc_mnp(dsi_clk, &dsi_mnp);
- if (ret) {
- DRM_DEBUG_KMS("dsi_calc_mnp failed\n");
- return;
- }
-
- dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
-
- DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n",
- dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl);
-
- vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
- vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, dsi_mnp.dsi_pll_div);
- vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl);
-}
-
-void vlv_enable_dsi_pll(struct intel_encoder *encoder)
-{
- struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- u32 tmp;
-
- DRM_DEBUG_KMS("\n");
-
- mutex_lock(&dev_priv->dpio_lock);
-
- vlv_configure_dsi_pll(encoder);
-
- /* wait at least 0.5 us after ungating before enabling VCO */
- usleep_range(1, 10);
-
- tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
- tmp |= DSI_PLL_VCO_EN;
- vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
-
- mutex_unlock(&dev_priv->dpio_lock);
-
- if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED, 20)) {
- DRM_ERROR("DSI PLL lock failed\n");
- return;
- }
-
- DRM_DEBUG_KMS("DSI PLL locked\n");
-}
-
-void vlv_disable_dsi_pll(struct intel_encoder *encoder)
-{
- struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- u32 tmp;
-
- DRM_DEBUG_KMS("\n");
-
- mutex_lock(&dev_priv->dpio_lock);
-
- tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
- tmp &= ~DSI_PLL_VCO_EN;
- tmp |= DSI_PLL_LDO_GATE;
- vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
-
- mutex_unlock(&dev_priv->dpio_lock);
-}
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 3c77365..7fa7df5 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -153,8 +153,6 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
flags |= DRM_MODE_FLAG_NVSYNC;
pipe_config->adjusted_mode.flags |= flags;
-
- pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
}
static void intel_disable_dvo(struct intel_encoder *encoder)
@@ -173,16 +171,11 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
- struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
u32 dvo_reg = intel_dvo->dev.dvo_reg;
u32 temp = I915_READ(dvo_reg);
I915_WRITE(dvo_reg, temp | DVO_ENABLE);
I915_READ(dvo_reg);
- intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
- &crtc->config.requested_mode,
- &crtc->config.adjusted_mode);
-
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
}
@@ -191,7 +184,6 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
{
struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
struct drm_crtc *crtc;
- struct intel_crtc_config *config;
/* dvo supports only 2 dpms states. */
if (mode != DRM_MODE_DPMS_ON)
@@ -212,16 +204,10 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
/* We call connector dpms manually below in case pipe dpms doesn't
* change due to cloning. */
if (mode == DRM_MODE_DPMS_ON) {
- config = &to_intel_crtc(crtc)->config;
-
intel_dvo->base.connectors_active = true;
intel_crtc_update_dpms(crtc);
- intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
- &config->requested_mode,
- &config->adjusted_mode);
-
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
} else {
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
@@ -281,6 +267,11 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder,
drm_mode_set_crtcinfo(adjusted_mode, 0);
}
+ if (intel_dvo->dev.dev_ops->mode_fixup)
+ return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev,
+ &pipe_config->requested_mode,
+ adjusted_mode);
+
return true;
}
@@ -308,6 +299,10 @@ static void intel_dvo_mode_set(struct intel_encoder *encoder)
break;
}
+ intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
+ &crtc->config.requested_mode,
+ adjusted_mode);
+
/* Save the data order, since I don't know what it should be set to. */
dvo_val = I915_READ(dvo_reg) &
(DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
@@ -375,6 +370,7 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
static void intel_dvo_destroy(struct drm_connector *connector)
{
+ drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -455,11 +451,11 @@ void intel_dvo_init(struct drm_device *dev)
int i;
int encoder_type = DRM_MODE_ENCODER_NONE;
- intel_dvo = kzalloc(sizeof(*intel_dvo), GFP_KERNEL);
+ intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL);
if (!intel_dvo)
return;
- intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+ intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_dvo);
return;
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fb.c
index 895fcb4..bc21000 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -78,8 +78,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
- mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
- DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
+ mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) /
+ 8), 64);
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
sizes->surface_depth);
@@ -184,27 +184,6 @@ out:
return ret;
}
-/** Sets the color ramps on behalf of RandR */
-static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- intel_crtc->lut_r[regno] = red >> 8;
- intel_crtc->lut_g[regno] = green >> 8;
- intel_crtc->lut_b[regno] = blue >> 8;
-}
-
-static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- *red = intel_crtc->lut_r[regno] << 8;
- *green = intel_crtc->lut_g[regno] << 8;
- *blue = intel_crtc->lut_b[regno] << 8;
-}
-
static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
.gamma_set = intel_crtc_fb_gamma_set,
.gamma_get = intel_crtc_fb_gamma_get,
@@ -237,7 +216,7 @@ int intel_fbdev_init(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL);
+ ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
if (!ifbdev)
return -ENOMEM;
@@ -246,7 +225,7 @@ int intel_fbdev_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &ifbdev->helper,
INTEL_INFO(dev)->num_pipes,
- 4);
+ INTELFB_CONN_LIMIT);
if (ret) {
kfree(ifbdev);
return ret;
@@ -299,13 +278,13 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state)
MODULE_LICENSE("GPL and additional rights");
-void intel_fbdev_output_poll_changed(struct drm_device *dev)
+void intel_fb_output_poll_changed(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
}
-void intel_fbdev_restore_mode(struct drm_device *dev)
+void intel_fb_restore_mode(struct drm_device *dev)
{
int ret;
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 03f9ca7..4148cc8 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -713,7 +713,6 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
u32 tmp, flags = 0;
- int dotclock;
tmp = I915_READ(intel_hdmi->hdmi_reg);
@@ -728,16 +727,6 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
flags |= DRM_MODE_FLAG_NVSYNC;
pipe_config->adjusted_mode.flags |= flags;
-
- if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
- dotclock = pipe_config->port_clock * 2 / 3;
- else
- dotclock = pipe_config->port_clock;
-
- if (HAS_PCH_SPLIT(dev_priv->dev))
- ironlake_check_encoder_dotclock(pipe_config, dotclock);
-
- pipe_config->adjusted_mode.crtc_clock = dotclock;
}
static void intel_enable_hdmi(struct intel_encoder *encoder)
@@ -847,7 +836,7 @@ static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
if (IS_G4X(dev))
return 165000;
- else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
+ else if (IS_HASWELL(dev))
return 300000;
else
return 225000;
@@ -873,7 +862,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_device *dev = encoder->base.dev;
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
- int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2;
+ int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2;
int portclock_limit = hdmi_portclock_limit(intel_hdmi);
int desired_bpp;
@@ -915,7 +904,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
pipe_config->pipe_bpp = desired_bpp;
}
- if (adjusted_mode->crtc_clock > portclock_limit) {
+ if (adjusted_mode->clock > portclock_limit) {
DRM_DEBUG_KMS("too high HDMI clock, rejecting mode\n");
return false;
}
@@ -1074,7 +1063,7 @@ done:
return 0;
}
-static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
+static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
{
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
struct drm_device *dev = encoder->base.dev;
@@ -1090,35 +1079,35 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
/* Enable clock channels for this port */
mutex_lock(&dev_priv->dpio_lock);
- val = vlv_dpio_read(dev_priv, pipe, DPIO_DATA_LANE_A(port));
+ val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port));
val = 0;
if (pipe)
val |= (1<<21);
else
val &= ~(1<<21);
val |= 0x001000c4;
- vlv_dpio_write(dev_priv, pipe, DPIO_DATA_CHANNEL(port), val);
+ vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val);
/* HDMI 1.0V-2dB */
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL4(port),
+ vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0);
+ vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port),
0x2b245f5f);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL2(port),
+ vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port),
0x5578b83a);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL3(port),
+ vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port),
0x0c782040);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX3_SWING_CTL4(port),
+ vlv_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(port),
0x2b247878);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER0(port), 0x00030000);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000);
+ vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port),
0x00002000);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port),
+ vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port),
DPIO_TX_OCALINIT_EN);
/* Program lane clock */
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF0(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port),
0x00760018);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF8(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port),
0x00400888);
mutex_unlock(&dev_priv->dpio_lock);
@@ -1127,60 +1116,55 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
vlv_wait_port_ready(dev_priv, port);
}
-static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
+static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder)
{
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc =
- to_intel_crtc(encoder->base.crtc);
int port = vlv_dport_to_channel(dport);
- int pipe = intel_crtc->pipe;
if (!IS_VALLEYVIEW(dev))
return;
/* Program Tx lane resets to default */
mutex_lock(&dev_priv->dpio_lock);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_TX(port),
DPIO_PCS_TX_LANE2_RESET |
DPIO_PCS_TX_LANE1_RESET);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port),
DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
(1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
DPIO_PCS_CLK_SOFT_RESET);
/* Fix up inter-pair skew failure */
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);
+ vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00);
+ vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500);
+ vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port),
+ vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port),
0x00002000);
- vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port),
+ vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port),
DPIO_TX_OCALINIT_EN);
mutex_unlock(&dev_priv->dpio_lock);
}
-static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
+static void intel_hdmi_post_disable(struct intel_encoder *encoder)
{
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- struct intel_crtc *intel_crtc =
- to_intel_crtc(encoder->base.crtc);
int port = vlv_dport_to_channel(dport);
- int pipe = intel_crtc->pipe;
/* Reset lanes to avoid HDMI flicker (VLV w/a) */
mutex_lock(&dev_priv->dpio_lock);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port), 0x00000000);
- vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port), 0x00e00060);
+ vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000);
+ vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060);
mutex_unlock(&dev_priv->dpio_lock);
}
static void intel_hdmi_destroy(struct drm_connector *connector)
{
+ drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -1227,7 +1211,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;
- connector->stereo_allowed = 1;
switch (port) {
case PORT_B:
@@ -1292,11 +1275,11 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
- intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
+ intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
if (!intel_dig_port)
return;
- intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+ intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_dig_port);
return;
@@ -1313,10 +1296,10 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
intel_encoder->get_config = intel_hdmi_get_config;
if (IS_VALLEYVIEW(dev)) {
- intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;
- intel_encoder->pre_enable = vlv_hdmi_pre_enable;
+ intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable;
+ intel_encoder->pre_enable = intel_hdmi_pre_enable;
intel_encoder->enable = vlv_enable_hdmi;
- intel_encoder->post_disable = vlv_hdmi_post_disable;
+ intel_encoder->post_disable = intel_hdmi_post_disable;
} else {
intel_encoder->enable = intel_enable_hdmi;
}
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 2ca17b1..d1c1e0f7 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -34,11 +34,6 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
-enum disp_clk {
- CDCLK,
- CZCLK
-};
-
struct gmbus_port {
const char *name;
int reg;
@@ -63,69 +58,10 @@ to_intel_gmbus(struct i2c_adapter *i2c)
return container_of(i2c, struct intel_gmbus, adapter);
}
-static int get_disp_clk_div(struct drm_i915_private *dev_priv,
- enum disp_clk clk)
-{
- u32 reg_val;
- int clk_ratio;
-
- reg_val = I915_READ(CZCLK_CDCLK_FREQ_RATIO);
-
- if (clk == CDCLK)
- clk_ratio =
- ((reg_val & CDCLK_FREQ_MASK) >> CDCLK_FREQ_SHIFT) + 1;
- else
- clk_ratio = (reg_val & CZCLK_FREQ_MASK) + 1;
-
- return clk_ratio;
-}
-
-static void gmbus_set_freq(struct drm_i915_private *dev_priv)
-{
- int vco_freq[] = { 800, 1600, 2000, 2400 };
- int gmbus_freq = 0, cdclk_div, hpll_freq;
-
- BUG_ON(!IS_VALLEYVIEW(dev_priv->dev));
-
- /* Skip setting the gmbus freq if BIOS has already programmed it */
- if (I915_READ(GMBUSFREQ_VLV) != 0xA0)
- return;
-
- /* Obtain SKU information */
- mutex_lock(&dev_priv->dpio_lock);
- hpll_freq =
- vlv_cck_read(dev_priv, CCK_FUSE_REG) & CCK_FUSE_HPLL_FREQ_MASK;
- mutex_unlock(&dev_priv->dpio_lock);
-
- /* Get the CDCLK divide ratio */
- cdclk_div = get_disp_clk_div(dev_priv, CDCLK);
-
- /*
- * Program the gmbus_freq based on the cdclk frequency.
- * BSpec erroneously claims we should aim for 4MHz, but
- * in fact 1MHz is the correct frequency.
- */
- if (cdclk_div)
- gmbus_freq = (vco_freq[hpll_freq] << 1) / cdclk_div;
-
- if (WARN_ON(gmbus_freq == 0))
- return;
-
- I915_WRITE(GMBUSFREQ_VLV, gmbus_freq);
-}
-
void
intel_i2c_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
-
- /*
- * In BIOS-less system, program the correct gmbus frequency
- * before reading edid.
- */
- if (IS_VALLEYVIEW(dev))
- gmbus_set_freq(dev_priv);
-
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0);
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0);
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index c3b4da7..b8af94a 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -92,7 +92,6 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 lvds_reg, tmp, flags = 0;
- int dotclock;
if (HAS_PCH_SPLIT(dev))
lvds_reg = PCH_LVDS;
@@ -117,13 +116,6 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
}
-
- dotclock = pipe_config->port_clock;
-
- if (HAS_PCH_SPLIT(dev_priv->dev))
- ironlake_check_encoder_dotclock(pipe_config, dotclock);
-
- pipe_config->adjusted_mode.crtc_clock = dotclock;
}
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
@@ -206,8 +198,7 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
- struct intel_connector *intel_connector =
- &lvds_encoder->attached_connector->base;
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct drm_i915_private *dev_priv = dev->dev_private;
u32 ctl_reg, stat_reg;
@@ -226,15 +217,13 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
DRM_ERROR("timed out waiting for panel to power on\n");
- intel_panel_enable_backlight(intel_connector);
+ intel_panel_enable_backlight(dev, intel_crtc->pipe);
}
static void intel_disable_lvds(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
- struct intel_connector *intel_connector =
- &lvds_encoder->attached_connector->base;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 ctl_reg, stat_reg;
@@ -246,7 +235,7 @@ static void intel_disable_lvds(struct intel_encoder *encoder)
stat_reg = PP_STATUS;
}
- intel_panel_disable_backlight(intel_connector);
+ intel_panel_disable_backlight(dev);
I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
@@ -477,6 +466,7 @@ static void intel_lvds_destroy(struct drm_connector *connector)
intel_panel_fini(&lvds_connector->base.panel);
+ drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -812,8 +802,7 @@ static bool lvds_is_present_in_vbt(struct drm_device *dev,
return true;
for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
- union child_device_config *uchild = dev_priv->vbt.child_dev + i;
- struct old_child_dev_config *child = &uchild->old;
+ struct child_device_config *child = dev_priv->vbt.child_dev + i;
/* If the device type is not LFP, continue.
* We have to check both the new identifiers as well as the
@@ -967,11 +956,11 @@ void intel_lvds_init(struct drm_device *dev)
}
}
- lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
+ lvds_encoder = kzalloc(sizeof(struct intel_lvds_encoder), GFP_KERNEL);
if (!lvds_encoder)
return;
- lvds_connector = kzalloc(sizeof(*lvds_connector), GFP_KERNEL);
+ lvds_connector = kzalloc(sizeof(struct intel_lvds_connector), GFP_KERNEL);
if (!lvds_connector) {
kfree(lvds_encoder);
return;
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 6d69a9b..119771f 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -36,11 +36,8 @@
#include "i915_drv.h"
#include "intel_drv.h"
-#define PCI_ASLE 0xe4
-#define PCI_ASLS 0xfc
-#define PCI_SWSCI 0xe8
-#define PCI_SWSCI_SCISEL (1 << 15)
-#define PCI_SWSCI_GSSCIE (1 << 0)
+#define PCI_ASLE 0xe4
+#define PCI_ASLS 0xfc
#define OPREGION_HEADER_OFFSET 0
#define OPREGION_ACPI_OFFSET 0x100
@@ -110,38 +107,25 @@ struct opregion_asle {
u32 epfm; /* enabled panel fitting modes */
u8 plut[74]; /* panel LUT and identifier */
u32 pfmb; /* PWM freq and min brightness */
- u32 cddv; /* color correction default values */
- u32 pcft; /* power conservation features */
- u32 srot; /* supported rotation angles */
- u32 iuer; /* IUER events */
- u8 rsvd[86];
+ u8 rsvd[102];
} __attribute__((packed));
/* Driver readiness indicator */
#define ASLE_ARDY_READY (1 << 0)
#define ASLE_ARDY_NOT_READY (0 << 0)
-/* ASLE Interrupt Command (ASLC) bits */
-#define ASLC_SET_ALS_ILLUM (1 << 0)
-#define ASLC_SET_BACKLIGHT (1 << 1)
-#define ASLC_SET_PFIT (1 << 2)
-#define ASLC_SET_PWM_FREQ (1 << 3)
-#define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4)
-#define ASLC_BUTTON_ARRAY (1 << 5)
-#define ASLC_CONVERTIBLE_INDICATOR (1 << 6)
-#define ASLC_DOCKING_INDICATOR (1 << 7)
-#define ASLC_ISCT_STATE_CHANGE (1 << 8)
-#define ASLC_REQ_MSK 0x1ff
-/* response bits */
-#define ASLC_ALS_ILLUM_FAILED (1 << 10)
-#define ASLC_BACKLIGHT_FAILED (1 << 12)
-#define ASLC_PFIT_FAILED (1 << 14)
-#define ASLC_PWM_FREQ_FAILED (1 << 16)
-#define ASLC_ROTATION_ANGLES_FAILED (1 << 18)
-#define ASLC_BUTTON_ARRAY_FAILED (1 << 20)
-#define ASLC_CONVERTIBLE_FAILED (1 << 22)
-#define ASLC_DOCKING_FAILED (1 << 24)
-#define ASLC_ISCT_STATE_FAILED (1 << 26)
+/* ASLE irq request bits */
+#define ASLE_SET_ALS_ILLUM (1 << 0)
+#define ASLE_SET_BACKLIGHT (1 << 1)
+#define ASLE_SET_PFIT (1 << 2)
+#define ASLE_SET_PWM_FREQ (1 << 3)
+#define ASLE_REQ_MSK 0xf
+
+/* response bits of ASLE irq request */
+#define ASLE_ALS_ILLUM_FAILED (1<<10)
+#define ASLE_BACKLIGHT_FAILED (1<<12)
+#define ASLE_PFIT_FAILED (1<<14)
+#define ASLE_PWM_FREQ_FAILED (1<<16)
/* Technology enabled indicator */
#define ASLE_TCHE_ALS_EN (1 << 0)
@@ -167,60 +151,6 @@ struct opregion_asle {
#define ASLE_CBLV_VALID (1<<31)
-/* IUER */
-#define ASLE_IUER_DOCKING (1 << 7)
-#define ASLE_IUER_CONVERTIBLE (1 << 6)
-#define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4)
-#define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3)
-#define ASLE_IUER_VOLUME_UP_BTN (1 << 2)
-#define ASLE_IUER_WINDOWS_BTN (1 << 1)
-#define ASLE_IUER_POWER_BTN (1 << 0)
-
-/* Software System Control Interrupt (SWSCI) */
-#define SWSCI_SCIC_INDICATOR (1 << 0)
-#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
-#define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1)
-#define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8
-#define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8)
-#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
-#define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8)
-#define SWSCI_SCIC_EXIT_STATUS_SHIFT 5
-#define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5)
-#define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1
-
-#define SWSCI_FUNCTION_CODE(main, sub) \
- ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
- (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
-
-/* SWSCI: Get BIOS Data (GBDA) */
-#define SWSCI_GBDA 4
-#define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
-#define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
-#define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
-#define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
-#define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
-#define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
-#define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
-
-/* SWSCI: System BIOS Callbacks (SBCB) */
-#define SWSCI_SBCB 6
-#define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
-#define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
-#define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
-#define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
-#define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
-#define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
-#define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
-#define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
-#define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
-#define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
-#define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
-#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
-#define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
-#define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
-#define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
-#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
-
#define ACPI_OTHER_OUTPUT (0<<8)
#define ACPI_VGA_OUTPUT (1<<8)
#define ACPI_TV_OUTPUT (2<<8)
@@ -228,224 +158,24 @@ struct opregion_asle {
#define ACPI_LVDS_OUTPUT (4<<8)
#ifdef CONFIG_ACPI
-static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct opregion_swsci __iomem *swsci = dev_priv->opregion.swsci;
- u32 main_function, sub_function, scic;
- u16 pci_swsci;
- u32 dslp;
-
- if (!swsci)
- return -ENODEV;
-
- main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >>
- SWSCI_SCIC_MAIN_FUNCTION_SHIFT;
- sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >>
- SWSCI_SCIC_SUB_FUNCTION_SHIFT;
-
- /* Check if we can call the function. See swsci_setup for details. */
- if (main_function == SWSCI_SBCB) {
- if ((dev_priv->opregion.swsci_sbcb_sub_functions &
- (1 << sub_function)) == 0)
- return -EINVAL;
- } else if (main_function == SWSCI_GBDA) {
- if ((dev_priv->opregion.swsci_gbda_sub_functions &
- (1 << sub_function)) == 0)
- return -EINVAL;
- }
-
- /* Driver sleep timeout in ms. */
- dslp = ioread32(&swsci->dslp);
- if (!dslp) {
- /* The spec says 2ms should be the default, but it's too small
- * for some machines. */
- dslp = 50;
- } else if (dslp > 500) {
- /* Hey bios, trust must be earned. */
- WARN_ONCE(1, "excessive driver sleep timeout (DSPL) %u\n", dslp);
- dslp = 500;
- }
-
- /* The spec tells us to do this, but we are the only user... */
- scic = ioread32(&swsci->scic);
- if (scic & SWSCI_SCIC_INDICATOR) {
- DRM_DEBUG_DRIVER("SWSCI request already in progress\n");
- return -EBUSY;
- }
-
- scic = function | SWSCI_SCIC_INDICATOR;
-
- iowrite32(parm, &swsci->parm);
- iowrite32(scic, &swsci->scic);
-
- /* Ensure SCI event is selected and event trigger is cleared. */
- pci_read_config_word(dev->pdev, PCI_SWSCI, &pci_swsci);
- if (!(pci_swsci & PCI_SWSCI_SCISEL) || (pci_swsci & PCI_SWSCI_GSSCIE)) {
- pci_swsci |= PCI_SWSCI_SCISEL;
- pci_swsci &= ~PCI_SWSCI_GSSCIE;
- pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
- }
-
- /* Use event trigger to tell bios to check the mail. */
- pci_swsci |= PCI_SWSCI_GSSCIE;
- pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
-
- /* Poll for the result. */
-#define C (((scic = ioread32(&swsci->scic)) & SWSCI_SCIC_INDICATOR) == 0)
- if (wait_for(C, dslp)) {
- DRM_DEBUG_DRIVER("SWSCI request timed out\n");
- return -ETIMEDOUT;
- }
-
- scic = (scic & SWSCI_SCIC_EXIT_STATUS_MASK) >>
- SWSCI_SCIC_EXIT_STATUS_SHIFT;
-
- /* Note: scic == 0 is an error! */
- if (scic != SWSCI_SCIC_EXIT_STATUS_SUCCESS) {
- DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic);
- return -EIO;
- }
-
- if (parm_out)
- *parm_out = ioread32(&swsci->parm);
-
- return 0;
-
-#undef C
-}
-
-#define DISPLAY_TYPE_CRT 0
-#define DISPLAY_TYPE_TV 1
-#define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL 2
-#define DISPLAY_TYPE_INTERNAL_FLAT_PANEL 3
-
-int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
- bool enable)
-{
- struct drm_device *dev = intel_encoder->base.dev;
- u32 parm = 0;
- u32 type = 0;
- u32 port;
-
- /* don't care about old stuff for now */
- if (!HAS_DDI(dev))
- return 0;
-
- port = intel_ddi_get_encoder_port(intel_encoder);
- if (port == PORT_E) {
- port = 0;
- } else {
- parm |= 1 << port;
- port++;
- }
-
- if (!enable)
- parm |= 4 << 8;
-
- switch (intel_encoder->type) {
- case INTEL_OUTPUT_ANALOG:
- type = DISPLAY_TYPE_CRT;
- break;
- case INTEL_OUTPUT_UNKNOWN:
- case INTEL_OUTPUT_DISPLAYPORT:
- case INTEL_OUTPUT_HDMI:
- type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL;
- break;
- case INTEL_OUTPUT_EDP:
- type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL;
- break;
- default:
- WARN_ONCE(1, "unsupported intel_encoder type %d\n",
- intel_encoder->type);
- return -EINVAL;
- }
-
- parm |= type << (16 + port * 3);
-
- return swsci(dev, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL);
-}
-
-static const struct {
- pci_power_t pci_power_state;
- u32 parm;
-} power_state_map[] = {
- { PCI_D0, 0x00 },
- { PCI_D1, 0x01 },
- { PCI_D2, 0x02 },
- { PCI_D3hot, 0x04 },
- { PCI_D3cold, 0x04 },
-};
-
-int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
-{
- int i;
-
- if (!HAS_DDI(dev))
- return 0;
-
- for (i = 0; i < ARRAY_SIZE(power_state_map); i++) {
- if (state == power_state_map[i].pci_power_state)
- return swsci(dev, SWSCI_SBCB_ADAPTER_POWER_STATE,
- power_state_map[i].parm, NULL);
- }
-
- return -EINVAL;
-}
-
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_encoder *encoder;
- struct drm_connector *connector;
- struct intel_connector *intel_connector = NULL;
- struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
- u32 ret = 0;
- bool found = false;
DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
if (!(bclp & ASLE_BCLP_VALID))
- return ASLC_BACKLIGHT_FAILED;
+ return ASLE_BACKLIGHT_FAILED;
bclp &= ASLE_BCLP_MSK;
if (bclp > 255)
- return ASLC_BACKLIGHT_FAILED;
-
- mutex_lock(&dev->mode_config.mutex);
- /*
- * Could match the OpRegion connector here instead, but we'd also need
- * to verify the connector could handle a backlight call.
- */
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
- if (encoder->crtc == crtc) {
- found = true;
- break;
- }
-
- if (!found) {
- ret = ASLC_BACKLIGHT_FAILED;
- goto out;
- }
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- if (connector->encoder == encoder)
- intel_connector = to_intel_connector(connector);
-
- if (!intel_connector) {
- ret = ASLC_BACKLIGHT_FAILED;
- goto out;
- }
+ return ASLE_BACKLIGHT_FAILED;
- DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
- intel_panel_set_backlight(intel_connector, bclp, 255);
+ intel_panel_set_backlight(dev, bclp, 255);
iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
-out:
- mutex_unlock(&dev->mode_config.mutex);
-
- return ret;
+ return 0;
}
static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
@@ -453,13 +183,13 @@ static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
/* alsi is the current ALS reading in lux. 0 indicates below sensor
range, 0xffff indicates above sensor range. 1-0xfffe are valid */
DRM_DEBUG_DRIVER("Illum is not supported\n");
- return ASLC_ALS_ILLUM_FAILED;
+ return ASLE_ALS_ILLUM_FAILED;
}
static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
{
DRM_DEBUG_DRIVER("PWM freq is not supported\n");
- return ASLC_PWM_FREQ_FAILED;
+ return ASLE_PWM_FREQ_FAILED;
}
static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
@@ -467,118 +197,39 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
/* Panel fitting is currently controlled by the X code, so this is a
noop until modesetting support works fully */
DRM_DEBUG_DRIVER("Pfit is not supported\n");
- return ASLC_PFIT_FAILED;
-}
-
-static u32 asle_set_supported_rotation_angles(struct drm_device *dev, u32 srot)
-{
- DRM_DEBUG_DRIVER("SROT is not supported\n");
- return ASLC_ROTATION_ANGLES_FAILED;
-}
-
-static u32 asle_set_button_array(struct drm_device *dev, u32 iuer)
-{
- if (!iuer)
- DRM_DEBUG_DRIVER("Button array event is not supported (nothing)\n");
- if (iuer & ASLE_IUER_ROTATION_LOCK_BTN)
- DRM_DEBUG_DRIVER("Button array event is not supported (rotation lock)\n");
- if (iuer & ASLE_IUER_VOLUME_DOWN_BTN)
- DRM_DEBUG_DRIVER("Button array event is not supported (volume down)\n");
- if (iuer & ASLE_IUER_VOLUME_UP_BTN)
- DRM_DEBUG_DRIVER("Button array event is not supported (volume up)\n");
- if (iuer & ASLE_IUER_WINDOWS_BTN)
- DRM_DEBUG_DRIVER("Button array event is not supported (windows)\n");
- if (iuer & ASLE_IUER_POWER_BTN)
- DRM_DEBUG_DRIVER("Button array event is not supported (power)\n");
-
- return ASLC_BUTTON_ARRAY_FAILED;
-}
-
-static u32 asle_set_convertible(struct drm_device *dev, u32 iuer)
-{
- if (iuer & ASLE_IUER_CONVERTIBLE)
- DRM_DEBUG_DRIVER("Convertible is not supported (clamshell)\n");
- else
- DRM_DEBUG_DRIVER("Convertible is not supported (slate)\n");
-
- return ASLC_CONVERTIBLE_FAILED;
+ return ASLE_PFIT_FAILED;
}
-static u32 asle_set_docking(struct drm_device *dev, u32 iuer)
-{
- if (iuer & ASLE_IUER_DOCKING)
- DRM_DEBUG_DRIVER("Docking is not supported (docked)\n");
- else
- DRM_DEBUG_DRIVER("Docking is not supported (undocked)\n");
-
- return ASLC_DOCKING_FAILED;
-}
-
-static u32 asle_isct_state(struct drm_device *dev)
-{
- DRM_DEBUG_DRIVER("ISCT is not supported\n");
- return ASLC_ISCT_STATE_FAILED;
-}
-
-static void asle_work(struct work_struct *work)
+void intel_opregion_asle_intr(struct drm_device *dev)
{
- struct intel_opregion *opregion =
- container_of(work, struct intel_opregion, asle_work);
- struct drm_i915_private *dev_priv =
- container_of(opregion, struct drm_i915_private, opregion);
- struct drm_device *dev = dev_priv->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
- u32 aslc_stat = 0;
- u32 aslc_req;
+ u32 asle_stat = 0;
+ u32 asle_req;
if (!asle)
return;
- aslc_req = ioread32(&asle->aslc);
+ asle_req = ioread32(&asle->aslc) & ASLE_REQ_MSK;
- if (!(aslc_req & ASLC_REQ_MSK)) {
- DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n",
- aslc_req);
+ if (!asle_req) {
+ DRM_DEBUG_DRIVER("non asle set request??\n");
return;
}
- if (aslc_req & ASLC_SET_ALS_ILLUM)
- aslc_stat |= asle_set_als_illum(dev, ioread32(&asle->alsi));
-
- if (aslc_req & ASLC_SET_BACKLIGHT)
- aslc_stat |= asle_set_backlight(dev, ioread32(&asle->bclp));
-
- if (aslc_req & ASLC_SET_PFIT)
- aslc_stat |= asle_set_pfit(dev, ioread32(&asle->pfit));
-
- if (aslc_req & ASLC_SET_PWM_FREQ)
- aslc_stat |= asle_set_pwm_freq(dev, ioread32(&asle->pfmb));
+ if (asle_req & ASLE_SET_ALS_ILLUM)
+ asle_stat |= asle_set_als_illum(dev, ioread32(&asle->alsi));
- if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES)
- aslc_stat |= asle_set_supported_rotation_angles(dev,
- ioread32(&asle->srot));
+ if (asle_req & ASLE_SET_BACKLIGHT)
+ asle_stat |= asle_set_backlight(dev, ioread32(&asle->bclp));
- if (aslc_req & ASLC_BUTTON_ARRAY)
- aslc_stat |= asle_set_button_array(dev, ioread32(&asle->iuer));
+ if (asle_req & ASLE_SET_PFIT)
+ asle_stat |= asle_set_pfit(dev, ioread32(&asle->pfit));
- if (aslc_req & ASLC_CONVERTIBLE_INDICATOR)
- aslc_stat |= asle_set_convertible(dev, ioread32(&asle->iuer));
+ if (asle_req & ASLE_SET_PWM_FREQ)
+ asle_stat |= asle_set_pwm_freq(dev, ioread32(&asle->pfmb));
- if (aslc_req & ASLC_DOCKING_INDICATOR)
- aslc_stat |= asle_set_docking(dev, ioread32(&asle->iuer));
-
- if (aslc_req & ASLC_ISCT_STATE_CHANGE)
- aslc_stat |= asle_isct_state(dev);
-
- iowrite32(aslc_stat, &asle->aslc);
-}
-
-void intel_opregion_asle_intr(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (dev_priv->opregion.asle)
- schedule_work(&dev_priv->opregion.asle_work);
+ iowrite32(asle_stat, &asle->aslc);
}
#define ACPI_EV_DISPLAY_SWITCH (1<<0)
@@ -638,7 +289,7 @@ static void intel_didl_outputs(struct drm_device *dev)
u32 temp;
int i = 0;
- handle = ACPI_HANDLE(&dev->pdev->dev);
+ handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
if (!handle || acpi_bus_get_device(handle, &acpi_dev))
return;
@@ -781,8 +432,6 @@ void intel_opregion_fini(struct drm_device *dev)
if (opregion->asle)
iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy);
- cancel_work_sync(&dev_priv->opregion.asle_work);
-
if (opregion->acpi) {
iowrite32(0, &opregion->acpi->drdy);
@@ -797,68 +446,8 @@ void intel_opregion_fini(struct drm_device *dev)
opregion->swsci = NULL;
opregion->asle = NULL;
opregion->vbt = NULL;
- opregion->lid_state = NULL;
}
-
-static void swsci_setup(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_opregion *opregion = &dev_priv->opregion;
- bool requested_callbacks = false;
- u32 tmp;
-
- /* Sub-function code 0 is okay, let's allow them. */
- opregion->swsci_gbda_sub_functions = 1;
- opregion->swsci_sbcb_sub_functions = 1;
-
- /* We use GBDA to ask for supported GBDA calls. */
- if (swsci(dev, SWSCI_GBDA_SUPPORTED_CALLS, 0, &tmp) == 0) {
- /* make the bits match the sub-function codes */
- tmp <<= 1;
- opregion->swsci_gbda_sub_functions |= tmp;
- }
-
- /*
- * We also use GBDA to ask for _requested_ SBCB callbacks. The driver
- * must not call interfaces that are not specifically requested by the
- * bios.
- */
- if (swsci(dev, SWSCI_GBDA_REQUESTED_CALLBACKS, 0, &tmp) == 0) {
- /* here, the bits already match sub-function codes */
- opregion->swsci_sbcb_sub_functions |= tmp;
- requested_callbacks = true;
- }
-
- /*
- * But we use SBCB to ask for _supported_ SBCB calls. This does not mean
- * the callback is _requested_. But we still can't call interfaces that
- * are not requested.
- */
- if (swsci(dev, SWSCI_SBCB_SUPPORTED_CALLBACKS, 0, &tmp) == 0) {
- /* make the bits match the sub-function codes */
- u32 low = tmp & 0x7ff;
- u32 high = tmp & ~0xfff; /* bit 11 is reserved */
- tmp = (high << 4) | (low << 1) | 1;
-
- /* best guess what to do with supported wrt requested */
- if (requested_callbacks) {
- u32 req = opregion->swsci_sbcb_sub_functions;
- if ((req & tmp) != req)
- DRM_DEBUG_DRIVER("SWSCI BIOS requested (%08x) SBCB callbacks that are not supported (%08x)\n", req, tmp);
- /* XXX: for now, trust the requested callbacks */
- /* opregion->swsci_sbcb_sub_functions &= tmp; */
- } else {
- opregion->swsci_sbcb_sub_functions |= tmp;
- }
- }
-
- DRM_DEBUG_DRIVER("SWSCI GBDA callbacks %08x, SBCB callbacks %08x\n",
- opregion->swsci_gbda_sub_functions,
- opregion->swsci_sbcb_sub_functions);
-}
-#else /* CONFIG_ACPI */
-static inline void swsci_setup(struct drm_device *dev) {}
-#endif /* CONFIG_ACPI */
+#endif
int intel_opregion_setup(struct drm_device *dev)
{
@@ -876,10 +465,6 @@ int intel_opregion_setup(struct drm_device *dev)
return -ENOTSUPP;
}
-#ifdef CONFIG_ACPI
- INIT_WORK(&opregion->asle_work, asle_work);
-#endif
-
base = acpi_os_ioremap(asls, OPREGION_SIZE);
if (!base)
return -ENOMEM;
@@ -905,7 +490,6 @@ int intel_opregion_setup(struct drm_device *dev)
if (mboxes & MBOX_SWSCI) {
DRM_DEBUG_DRIVER("SWSCI supported\n");
opregion->swsci = base + OPREGION_SWSCI_OFFSET;
- swsci_setup(dev);
}
if (mboxes & MBOX_ASLE) {
DRM_DEBUG_DRIVER("ASLE supported\n");
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index a98a990..ddfd0ae 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -821,11 +821,14 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
struct intel_crtc *crtc)
{
+ drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+
if (!crtc->active)
return -EINVAL;
/* can't use the overlay with double wide pipe */
- if (crtc->config.double_wide)
+ if (INTEL_INFO(overlay->dev)->gen < 4 &&
+ (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
return -EINVAL;
return 0;
@@ -1053,7 +1056,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
return ret;
}
- params = kmalloc(sizeof(*params), GFP_KERNEL);
+ params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
if (!params)
return -ENOMEM;
@@ -1320,7 +1323,7 @@ void intel_setup_overlay(struct drm_device *dev)
if (!HAS_OVERLAY(dev))
return;
- overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
+ overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
if (!overlay)
return;
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index f161ac0..293564a 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -50,22 +50,23 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode)
{
- struct drm_display_mode *adjusted_mode;
+ struct drm_display_mode *mode, *adjusted_mode;
int x, y, width, height;
+ mode = &pipe_config->requested_mode;
adjusted_mode = &pipe_config->adjusted_mode;
x = y = width = height = 0;
/* Native modes don't need fitting */
- if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
- adjusted_mode->vdisplay == pipe_config->pipe_src_h)
+ if (adjusted_mode->hdisplay == mode->hdisplay &&
+ adjusted_mode->vdisplay == mode->vdisplay)
goto done;
switch (fitting_mode) {
case DRM_MODE_SCALE_CENTER:
- width = pipe_config->pipe_src_w;
- height = pipe_config->pipe_src_h;
+ width = mode->hdisplay;
+ height = mode->vdisplay;
x = (adjusted_mode->hdisplay - width + 1)/2;
y = (adjusted_mode->vdisplay - height + 1)/2;
break;
@@ -73,19 +74,17 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
case DRM_MODE_SCALE_ASPECT:
/* Scale but preserve the aspect ratio */
{
- u32 scaled_width = adjusted_mode->hdisplay
- * pipe_config->pipe_src_h;
- u32 scaled_height = pipe_config->pipe_src_w
- * adjusted_mode->vdisplay;
+ u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
+ u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
if (scaled_width > scaled_height) { /* pillar */
- width = scaled_height / pipe_config->pipe_src_h;
+ width = scaled_height / mode->vdisplay;
if (width & 1)
width++;
x = (adjusted_mode->hdisplay - width + 1) / 2;
y = 0;
height = adjusted_mode->vdisplay;
} else if (scaled_width < scaled_height) { /* letter */
- height = scaled_width / pipe_config->pipe_src_w;
+ height = scaled_width / mode->hdisplay;
if (height & 1)
height++;
y = (adjusted_mode->vdisplay - height + 1) / 2;
@@ -172,96 +171,20 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
return (FACTOR * ratio + FACTOR/2) / FACTOR;
}
-static void i965_scale_aspect(struct intel_crtc_config *pipe_config,
- u32 *pfit_control)
-{
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
- u32 scaled_width = adjusted_mode->hdisplay *
- pipe_config->pipe_src_h;
- u32 scaled_height = pipe_config->pipe_src_w *
- adjusted_mode->vdisplay;
-
- /* 965+ is easy, it does everything in hw */
- if (scaled_width > scaled_height)
- *pfit_control |= PFIT_ENABLE |
- PFIT_SCALING_PILLAR;
- else if (scaled_width < scaled_height)
- *pfit_control |= PFIT_ENABLE |
- PFIT_SCALING_LETTER;
- else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w)
- *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
-}
-
-static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
- u32 *pfit_control, u32 *pfit_pgm_ratios,
- u32 *border)
-{
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
- u32 scaled_width = adjusted_mode->hdisplay *
- pipe_config->pipe_src_h;
- u32 scaled_height = pipe_config->pipe_src_w *
- adjusted_mode->vdisplay;
- u32 bits;
-
- /*
- * For earlier chips we have to calculate the scaling
- * ratio by hand and program it into the
- * PFIT_PGM_RATIO register
- */
- if (scaled_width > scaled_height) { /* pillar */
- centre_horizontally(adjusted_mode,
- scaled_height /
- pipe_config->pipe_src_h);
-
- *border = LVDS_BORDER_ENABLE;
- if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) {
- bits = panel_fitter_scaling(pipe_config->pipe_src_h,
- adjusted_mode->vdisplay);
-
- *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
- bits << PFIT_VERT_SCALE_SHIFT);
- *pfit_control |= (PFIT_ENABLE |
- VERT_INTERP_BILINEAR |
- HORIZ_INTERP_BILINEAR);
- }
- } else if (scaled_width < scaled_height) { /* letter */
- centre_vertically(adjusted_mode,
- scaled_width /
- pipe_config->pipe_src_w);
-
- *border = LVDS_BORDER_ENABLE;
- if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
- bits = panel_fitter_scaling(pipe_config->pipe_src_w,
- adjusted_mode->hdisplay);
-
- *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
- bits << PFIT_VERT_SCALE_SHIFT);
- *pfit_control |= (PFIT_ENABLE |
- VERT_INTERP_BILINEAR |
- HORIZ_INTERP_BILINEAR);
- }
- } else {
- /* Aspects match, Let hw scale both directions */
- *pfit_control |= (PFIT_ENABLE |
- VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
- VERT_INTERP_BILINEAR |
- HORIZ_INTERP_BILINEAR);
- }
-}
-
void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode)
{
struct drm_device *dev = intel_crtc->base.dev;
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
- struct drm_display_mode *adjusted_mode;
+ struct drm_display_mode *mode, *adjusted_mode;
+ mode = &pipe_config->requested_mode;
adjusted_mode = &pipe_config->adjusted_mode;
/* Native modes don't need fitting */
- if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
- adjusted_mode->vdisplay == pipe_config->pipe_src_h)
+ if (adjusted_mode->hdisplay == mode->hdisplay &&
+ adjusted_mode->vdisplay == mode->vdisplay)
goto out;
switch (fitting_mode) {
@@ -270,25 +193,81 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
* For centered modes, we have to calculate border widths &
* heights and modify the values programmed into the CRTC.
*/
- centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
- centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
+ centre_horizontally(adjusted_mode, mode->hdisplay);
+ centre_vertically(adjusted_mode, mode->vdisplay);
border = LVDS_BORDER_ENABLE;
break;
case DRM_MODE_SCALE_ASPECT:
/* Scale but preserve the aspect ratio */
- if (INTEL_INFO(dev)->gen >= 4)
- i965_scale_aspect(pipe_config, &pfit_control);
- else
- i9xx_scale_aspect(pipe_config, &pfit_control,
- &pfit_pgm_ratios, &border);
+ if (INTEL_INFO(dev)->gen >= 4) {
+ u32 scaled_width = adjusted_mode->hdisplay *
+ mode->vdisplay;
+ u32 scaled_height = mode->hdisplay *
+ adjusted_mode->vdisplay;
+
+ /* 965+ is easy, it does everything in hw */
+ if (scaled_width > scaled_height)
+ pfit_control |= PFIT_ENABLE |
+ PFIT_SCALING_PILLAR;
+ else if (scaled_width < scaled_height)
+ pfit_control |= PFIT_ENABLE |
+ PFIT_SCALING_LETTER;
+ else if (adjusted_mode->hdisplay != mode->hdisplay)
+ pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
+ } else {
+ u32 scaled_width = adjusted_mode->hdisplay *
+ mode->vdisplay;
+ u32 scaled_height = mode->hdisplay *
+ adjusted_mode->vdisplay;
+ /*
+ * For earlier chips we have to calculate the scaling
+ * ratio by hand and program it into the
+ * PFIT_PGM_RATIO register
+ */
+ if (scaled_width > scaled_height) { /* pillar */
+ centre_horizontally(adjusted_mode,
+ scaled_height /
+ mode->vdisplay);
+
+ border = LVDS_BORDER_ENABLE;
+ if (mode->vdisplay != adjusted_mode->vdisplay) {
+ u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay);
+ pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+ bits << PFIT_VERT_SCALE_SHIFT);
+ pfit_control |= (PFIT_ENABLE |
+ VERT_INTERP_BILINEAR |
+ HORIZ_INTERP_BILINEAR);
+ }
+ } else if (scaled_width < scaled_height) { /* letter */
+ centre_vertically(adjusted_mode,
+ scaled_width /
+ mode->hdisplay);
+
+ border = LVDS_BORDER_ENABLE;
+ if (mode->hdisplay != adjusted_mode->hdisplay) {
+ u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay);
+ pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+ bits << PFIT_VERT_SCALE_SHIFT);
+ pfit_control |= (PFIT_ENABLE |
+ VERT_INTERP_BILINEAR |
+ HORIZ_INTERP_BILINEAR);
+ }
+ } else {
+ /* Aspects match, Let hw scale both directions */
+ pfit_control |= (PFIT_ENABLE |
+ VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
+ VERT_INTERP_BILINEAR |
+ HORIZ_INTERP_BILINEAR);
+ }
+ }
break;
case DRM_MODE_SCALE_FULLSCREEN:
/*
* Full scaling, even if it changes the aspect ratio.
* Fortunately this is all done for us in hw.
*/
- if (pipe_config->pipe_src_h != adjusted_mode->vdisplay ||
- pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
+ if (mode->vdisplay != adjusted_mode->vdisplay ||
+ mode->hdisplay != adjusted_mode->hdisplay) {
pfit_control |= PFIT_ENABLE;
if (INTEL_INFO(dev)->gen >= 4)
pfit_control |= PFIT_SCALING_AUTO;
@@ -329,7 +308,7 @@ static int is_backlight_combination_mode(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (IS_GEN4(dev))
+ if (INTEL_INFO(dev)->gen >= 4)
return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
if (IS_GEN2(dev))
@@ -341,7 +320,7 @@ static int is_backlight_combination_mode(struct drm_device *dev)
/* XXX: query mode clock or hardware clock and program max PWM appropriately
* when it's 0.
*/
-static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe)
+static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val;
@@ -358,21 +337,6 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe)
val = dev_priv->regfile.saveBLC_PWM_CTL2;
I915_WRITE(BLC_PWM_PCH_CTL2, val);
}
- } else if (IS_VALLEYVIEW(dev)) {
- val = I915_READ(VLV_BLC_PWM_CTL(pipe));
- if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
- dev_priv->regfile.saveBLC_PWM_CTL = val;
- dev_priv->regfile.saveBLC_PWM_CTL2 =
- I915_READ(VLV_BLC_PWM_CTL2(pipe));
- } else if (val == 0) {
- val = dev_priv->regfile.saveBLC_PWM_CTL;
- I915_WRITE(VLV_BLC_PWM_CTL(pipe), val);
- I915_WRITE(VLV_BLC_PWM_CTL2(pipe),
- dev_priv->regfile.saveBLC_PWM_CTL2);
- }
-
- if (!val)
- val = 0x0f42ffff;
} else {
val = I915_READ(BLC_PWM_CTL);
if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
@@ -392,12 +356,11 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe)
return val;
}
-static u32 intel_panel_get_max_backlight(struct drm_device *dev,
- enum pipe pipe)
+static u32 intel_panel_get_max_backlight(struct drm_device *dev)
{
u32 max;
- max = i915_read_blc_pwm_ctl(dev, pipe);
+ max = i915_read_blc_pwm_ctl(dev);
if (HAS_PCH_SPLIT(dev)) {
max >>= 16;
@@ -423,8 +386,7 @@ MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
"to dri-devel@lists.freedesktop.org, if your machine needs it. "
"It will then be included in an upcoming module version.");
module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
-static u32 intel_panel_compute_brightness(struct drm_device *dev,
- enum pipe pipe, u32 val)
+static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -433,7 +395,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
if (i915_panel_invert_brightness > 0 ||
dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
- u32 max = intel_panel_get_max_backlight(dev, pipe);
+ u32 max = intel_panel_get_max_backlight(dev);
if (max)
return max - val;
}
@@ -441,25 +403,18 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
return val;
}
-static u32 intel_panel_get_backlight(struct drm_device *dev,
- enum pipe pipe)
+static u32 intel_panel_get_backlight(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val;
unsigned long flags;
- int reg;
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
if (HAS_PCH_SPLIT(dev)) {
val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
} else {
- if (IS_VALLEYVIEW(dev))
- reg = VLV_BLC_PWM_CTL(pipe);
- else
- reg = BLC_PWM_CTL;
-
- val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
+ val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
if (INTEL_INFO(dev)->gen < 4)
val >>= 1;
@@ -471,7 +426,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
}
}
- val = intel_panel_compute_brightness(dev, pipe, val);
+ val = intel_panel_compute_brightness(dev, val);
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
@@ -486,21 +441,19 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
I915_WRITE(BLC_PWM_CPU_CTL, val | level);
}
-static void intel_panel_actually_set_backlight(struct drm_device *dev,
- enum pipe pipe, u32 level)
+static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 tmp;
- int reg;
DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
- level = intel_panel_compute_brightness(dev, pipe, level);
+ level = intel_panel_compute_brightness(dev, level);
if (HAS_PCH_SPLIT(dev))
return intel_pch_panel_set_backlight(dev, level);
if (is_backlight_combination_mode(dev)) {
- u32 max = intel_panel_get_max_backlight(dev, pipe);
+ u32 max = intel_panel_get_max_backlight(dev);
u8 lbpc;
/* we're screwed, but keep behaviour backwards compatible */
@@ -512,34 +465,23 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
}
- if (IS_VALLEYVIEW(dev))
- reg = VLV_BLC_PWM_CTL(pipe);
- else
- reg = BLC_PWM_CTL;
-
- tmp = I915_READ(reg);
+ tmp = I915_READ(BLC_PWM_CTL);
if (INTEL_INFO(dev)->gen < 4)
level <<= 1;
tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
- I915_WRITE(reg, tmp | level);
+ I915_WRITE(BLC_PWM_CTL, tmp | level);
}
/* set backlight brightness to level in range [0..max] */
-void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
- u32 max)
+void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
{
- struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe pipe = intel_get_pipe_from_connector(connector);
u32 freq;
unsigned long flags;
- if (pipe == INVALID_PIPE)
- return;
-
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
- freq = intel_panel_get_max_backlight(dev, pipe);
+ freq = intel_panel_get_max_backlight(dev);
if (!freq) {
/* we are screwed, bail out */
goto out;
@@ -556,21 +498,16 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
dev_priv->backlight.device->props.brightness = level;
if (dev_priv->backlight.enabled)
- intel_panel_actually_set_backlight(dev, pipe, level);
+ intel_panel_actually_set_backlight(dev, level);
out:
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
}
-void intel_panel_disable_backlight(struct intel_connector *connector)
+void intel_panel_disable_backlight(struct drm_device *dev)
{
- struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe pipe = intel_get_pipe_from_connector(connector);
unsigned long flags;
- if (pipe == INVALID_PIPE)
- return;
-
/*
* Do not disable backlight on the vgaswitcheroo path. When switching
* away from i915, the other client may depend on i915 to handle the
@@ -585,17 +522,12 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
dev_priv->backlight.enabled = false;
- intel_panel_actually_set_backlight(dev, pipe, 0);
+ intel_panel_actually_set_backlight(dev, 0);
if (INTEL_INFO(dev)->gen >= 4) {
uint32_t reg, tmp;
- if (HAS_PCH_SPLIT(dev))
- reg = BLC_PWM_CPU_CTL2;
- else if (IS_VALLEYVIEW(dev))
- reg = VLV_BLC_PWM_CTL2(pipe);
- else
- reg = BLC_PWM_CTL2;
+ reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
@@ -609,25 +541,18 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
}
-void intel_panel_enable_backlight(struct intel_connector *connector)
+void intel_panel_enable_backlight(struct drm_device *dev,
+ enum pipe pipe)
{
- struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe pipe = intel_get_pipe_from_connector(connector);
enum transcoder cpu_transcoder =
intel_pipe_to_cpu_transcoder(dev_priv, pipe);
unsigned long flags;
- if (pipe == INVALID_PIPE)
- return;
-
- DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
-
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
if (dev_priv->backlight.level == 0) {
- dev_priv->backlight.level = intel_panel_get_max_backlight(dev,
- pipe);
+ dev_priv->backlight.level = intel_panel_get_max_backlight(dev);
if (dev_priv->backlight.device)
dev_priv->backlight.device->props.brightness =
dev_priv->backlight.level;
@@ -636,12 +561,8 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
if (INTEL_INFO(dev)->gen >= 4) {
uint32_t reg, tmp;
- if (HAS_PCH_SPLIT(dev))
- reg = BLC_PWM_CPU_CTL2;
- else if (IS_VALLEYVIEW(dev))
- reg = VLV_BLC_PWM_CTL2(pipe);
- else
- reg = BLC_PWM_CTL2;
+ reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
+
tmp = I915_READ(reg);
@@ -681,41 +602,16 @@ set_level:
* registers are set.
*/
dev_priv->backlight.enabled = true;
- intel_panel_actually_set_backlight(dev, pipe,
- dev_priv->backlight.level);
+ intel_panel_actually_set_backlight(dev, dev_priv->backlight.level);
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
}
-/* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */
-static void intel_panel_init_backlight_regs(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (IS_VALLEYVIEW(dev)) {
- enum pipe pipe;
-
- for_each_pipe(pipe) {
- u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
-
- /* Skip if the modulation freq is already set */
- if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
- continue;
-
- cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
- I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) |
- cur_val);
- }
- }
-}
-
static void intel_panel_init_backlight(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- intel_panel_init_backlight_regs(dev);
-
- dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
+ dev_priv->backlight.level = intel_panel_get_backlight(dev);
dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
}
@@ -741,34 +637,19 @@ intel_panel_detect(struct drm_device *dev)
}
}
-#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
static int intel_panel_update_status(struct backlight_device *bd)
{
- struct intel_connector *connector = bl_get_data(bd);
- struct drm_device *dev = connector->base.dev;
-
- mutex_lock(&dev->mode_config.mutex);
- DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
- bd->props.brightness, bd->props.max_brightness);
- intel_panel_set_backlight(connector, bd->props.brightness,
+ struct drm_device *dev = bl_get_data(bd);
+ intel_panel_set_backlight(dev, bd->props.brightness,
bd->props.max_brightness);
- mutex_unlock(&dev->mode_config.mutex);
return 0;
}
static int intel_panel_get_brightness(struct backlight_device *bd)
{
- struct intel_connector *connector = bl_get_data(bd);
- struct drm_device *dev = connector->base.dev;
- enum pipe pipe;
-
- mutex_lock(&dev->mode_config.mutex);
- pipe = intel_get_pipe_from_connector(connector);
- mutex_unlock(&dev->mode_config.mutex);
- if (pipe == INVALID_PIPE)
- return 0;
-
- return intel_panel_get_backlight(connector->base.dev, pipe);
+ struct drm_device *dev = bl_get_data(bd);
+ return intel_panel_get_backlight(dev);
}
static const struct backlight_ops intel_panel_bl_ops = {
@@ -793,7 +674,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
props.brightness = dev_priv->backlight.level;
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
- props.max_brightness = intel_panel_get_max_backlight(dev, 0);
+ props.max_brightness = intel_panel_get_max_backlight(dev);
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
if (props.max_brightness == 0) {
@@ -802,8 +683,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
}
dev_priv->backlight.device =
backlight_device_register("intel_backlight",
- connector->kdev,
- to_intel_connector(connector),
+ &connector->kdev, dev,
&intel_panel_bl_ops, &props);
if (IS_ERR(dev_priv->backlight.device)) {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6e0d5e0..26c2ea3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -32,27 +32,6 @@
#include <linux/module.h>
#include <drm/i915_powerwell.h>
-/**
- * RC6 is a special power stage which allows the GPU to enter an very
- * low-voltage mode when idle, using down to 0V while at this stage. This
- * stage is entered automatically when the GPU is idle when RC6 support is
- * enabled, and as soon as new workload arises GPU wakes up automatically as well.
- *
- * There are different RC6 modes available in Intel GPU, which differentiate
- * among each other with the latency required to enter and leave RC6 and
- * voltage consumed by the GPU in different states.
- *
- * The combination of the following flags define which states GPU is allowed
- * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and
- * RC6pp is deepest RC6. Their support by hardware varies according to the
- * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one
- * which brings the most power savings; deeper states save more power, but
- * require higher latency to switch to and wake up.
- */
-#define INTEL_RC6_ENABLE (1<<0)
-#define INTEL_RC6p_ENABLE (1<<1)
-#define INTEL_RC6pp_ENABLE (1<<2)
-
/* FBC, or Frame Buffer Compression, is a technique employed to compress the
* framebuffer contents in-memory, aiming at reducing the required bandwidth
* during in-memory transfers and, therefore, reduce the power packet.
@@ -64,6 +43,14 @@
* i915.i915_enable_fbc parameter
*/
+static bool intel_crtc_active(struct drm_crtc *crtc)
+{
+ /* Be paranoid as we can arrive here with only partial
+ * state retrieved from the hardware during setup.
+ */
+ return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock;
+}
+
static void i8xx_disable_fbc(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -254,6 +241,18 @@ static void ironlake_disable_fbc(struct drm_device *dev)
dpfc_ctl &= ~DPFC_CTL_EN;
I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
+ if (IS_IVYBRIDGE(dev))
+ /* WaFbcDisableDpfcClockGating:ivb */
+ I915_WRITE(ILK_DSPCLK_GATE_D,
+ I915_READ(ILK_DSPCLK_GATE_D) &
+ ~ILK_DPFCUNIT_CLOCK_GATE_DISABLE);
+
+ if (IS_HASWELL(dev))
+ /* WaFbcDisableDpfcClockGating:hsw */
+ I915_WRITE(HSW_CLKGATE_DISABLE_PART_1,
+ I915_READ(HSW_CLKGATE_DISABLE_PART_1) &
+ ~HSW_DPFC_GATING_DISABLE);
+
DRM_DEBUG_KMS("disabled FBC\n");
}
}
@@ -283,10 +282,18 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
if (IS_IVYBRIDGE(dev)) {
/* WaFbcAsynchFlipDisableFbcQueue:ivb */
I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS);
+ /* WaFbcDisableDpfcClockGating:ivb */
+ I915_WRITE(ILK_DSPCLK_GATE_D,
+ I915_READ(ILK_DSPCLK_GATE_D) |
+ ILK_DPFCUNIT_CLOCK_GATE_DISABLE);
} else {
/* WaFbcAsynchFlipDisableFbcQueue:hsw */
I915_WRITE(HSW_PIPE_SLICE_CHICKEN_1(intel_crtc->pipe),
HSW_BYPASS_FBC_QUEUE);
+ /* WaFbcDisableDpfcClockGating:hsw */
+ I915_WRITE(HSW_CLKGATE_DISABLE_PART_1,
+ I915_READ(HSW_CLKGATE_DISABLE_PART_1) |
+ HSW_DPFC_GATING_DISABLE);
}
I915_WRITE(SNB_DPFC_CTL_SA,
@@ -371,7 +378,7 @@ static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
intel_cancel_fbc_work(dev_priv);
- work = kzalloc(sizeof(*work), GFP_KERNEL);
+ work = kzalloc(sizeof *work, GFP_KERNEL);
if (work == NULL) {
DRM_ERROR("Failed to allocate FBC work structure\n");
dev_priv->display.enable_fbc(crtc, interval);
@@ -451,8 +458,7 @@ void intel_update_fbc(struct drm_device *dev)
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
struct drm_i915_gem_object *obj;
- const struct drm_display_mode *adjusted_mode;
- unsigned int max_width, max_height;
+ unsigned int max_hdisplay, max_vdisplay;
if (!I915_HAS_FBC(dev)) {
set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED);
@@ -476,7 +482,7 @@ void intel_update_fbc(struct drm_device *dev)
*/
list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
if (intel_crtc_active(tmp_crtc) &&
- to_intel_crtc(tmp_crtc)->primary_enabled) {
+ !to_intel_crtc(tmp_crtc)->primary_disabled) {
if (crtc) {
if (set_no_fbc_reason(dev_priv, FBC_MULTIPLE_PIPES))
DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
@@ -496,7 +502,6 @@ void intel_update_fbc(struct drm_device *dev)
fb = crtc->fb;
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
- adjusted_mode = &intel_crtc->config.adjusted_mode;
if (i915_enable_fbc < 0 &&
INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) {
@@ -509,8 +514,8 @@ void intel_update_fbc(struct drm_device *dev)
DRM_DEBUG_KMS("fbc disabled per module param\n");
goto out_disable;
}
- if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
- (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
+ if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) ||
+ (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) {
if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
DRM_DEBUG_KMS("mode incompatible with compression, "
"disabling\n");
@@ -518,14 +523,14 @@ void intel_update_fbc(struct drm_device *dev)
}
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
- max_width = 4096;
- max_height = 2048;
+ max_hdisplay = 4096;
+ max_vdisplay = 2048;
} else {
- max_width = 2048;
- max_height = 1536;
+ max_hdisplay = 2048;
+ max_vdisplay = 1536;
}
- if (intel_crtc->config.pipe_src_w > max_width ||
- intel_crtc->config.pipe_src_h > max_height) {
+ if ((crtc->mode.hdisplay > max_hdisplay) ||
+ (crtc->mode.vdisplay > max_vdisplay)) {
if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE))
DRM_DEBUG_KMS("mode too large for compression, disabling\n");
goto out_disable;
@@ -1082,9 +1087,8 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev)
return enabled;
}
-static void pineview_update_wm(struct drm_crtc *unused_crtc)
+static void pineview_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = unused_crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
const struct cxsr_latency *latency;
@@ -1101,12 +1105,8 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
crtc = single_enabled_crtc(dev);
if (crtc) {
- const struct drm_display_mode *adjusted_mode;
+ int clock = crtc->mode.clock;
int pixel_size = crtc->fb->bits_per_pixel / 8;
- int clock;
-
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
- clock = adjusted_mode->crtc_clock;
/* Display SR */
wm = intel_calculate_wm(clock, &pineview_display_wm,
@@ -1166,7 +1166,6 @@ static bool g4x_compute_wm0(struct drm_device *dev,
int *cursor_wm)
{
struct drm_crtc *crtc;
- const struct drm_display_mode *adjusted_mode;
int htotal, hdisplay, clock, pixel_size;
int line_time_us, line_count;
int entries, tlb_miss;
@@ -1178,10 +1177,9 @@ static bool g4x_compute_wm0(struct drm_device *dev,
return false;
}
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
- clock = adjusted_mode->crtc_clock;
- htotal = adjusted_mode->crtc_htotal;
- hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+ htotal = crtc->mode.htotal;
+ hdisplay = crtc->mode.hdisplay;
+ clock = crtc->mode.clock;
pixel_size = crtc->fb->bits_per_pixel / 8;
/* Use the small buffer method to calculate plane watermark */
@@ -1252,7 +1250,6 @@ static bool g4x_compute_srwm(struct drm_device *dev,
int *display_wm, int *cursor_wm)
{
struct drm_crtc *crtc;
- const struct drm_display_mode *adjusted_mode;
int hdisplay, htotal, pixel_size, clock;
unsigned long line_time_us;
int line_count, line_size;
@@ -1265,10 +1262,9 @@ static bool g4x_compute_srwm(struct drm_device *dev,
}
crtc = intel_get_crtc_for_plane(dev, plane);
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
- clock = adjusted_mode->crtc_clock;
- htotal = adjusted_mode->crtc_htotal;
- hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+ hdisplay = crtc->mode.hdisplay;
+ htotal = crtc->mode.htotal;
+ clock = crtc->mode.clock;
pixel_size = crtc->fb->bits_per_pixel / 8;
line_time_us = (htotal * 1000) / clock;
@@ -1307,7 +1303,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev,
if (!intel_crtc_active(crtc))
return false;
- clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
+ clock = crtc->mode.clock; /* VESA DOT Clock */
pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */
entries = (clock / 1000) * pixel_size;
@@ -1369,9 +1365,8 @@ static void vlv_update_drain_latency(struct drm_device *dev)
#define single_plane_enabled(mask) is_power_of_2(mask)
-static void valleyview_update_wm(struct drm_crtc *crtc)
+static void valleyview_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = crtc->dev;
static const int sr_latency_ns = 12000;
struct drm_i915_private *dev_priv = dev->dev_private;
int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
@@ -1429,9 +1424,8 @@ static void valleyview_update_wm(struct drm_crtc *crtc)
(cursor_sr << DSPFW_CURSOR_SR_SHIFT));
}
-static void g4x_update_wm(struct drm_crtc *crtc)
+static void g4x_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = crtc->dev;
static const int sr_latency_ns = 12000;
struct drm_i915_private *dev_priv = dev->dev_private;
int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
@@ -1482,9 +1476,8 @@ static void g4x_update_wm(struct drm_crtc *crtc)
(cursor_sr << DSPFW_CURSOR_SR_SHIFT));
}
-static void i965_update_wm(struct drm_crtc *unused_crtc)
+static void i965_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = unused_crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
int srwm = 1;
@@ -1495,11 +1488,9 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
if (crtc) {
/* self-refresh has much higher latency */
static const int sr_latency_ns = 12000;
- const struct drm_display_mode *adjusted_mode =
- &to_intel_crtc(crtc)->config.adjusted_mode;
- int clock = adjusted_mode->crtc_clock;
- int htotal = adjusted_mode->crtc_htotal;
- int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+ int clock = crtc->mode.clock;
+ int htotal = crtc->mode.htotal;
+ int hdisplay = crtc->mode.hdisplay;
int pixel_size = crtc->fb->bits_per_pixel / 8;
unsigned long line_time_us;
int entries;
@@ -1550,9 +1541,8 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
}
-static void i9xx_update_wm(struct drm_crtc *unused_crtc)
+static void i9xx_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = unused_crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct intel_watermark_params *wm_info;
uint32_t fwater_lo;
@@ -1572,13 +1562,11 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
fifo_size = dev_priv->display.get_fifo_size(dev, 0);
crtc = intel_get_crtc_for_plane(dev, 0);
if (intel_crtc_active(crtc)) {
- const struct drm_display_mode *adjusted_mode;
int cpp = crtc->fb->bits_per_pixel / 8;
if (IS_GEN2(dev))
cpp = 4;
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
- planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+ planea_wm = intel_calculate_wm(crtc->mode.clock,
wm_info, fifo_size, cpp,
latency_ns);
enabled = crtc;
@@ -1588,13 +1576,11 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
fifo_size = dev_priv->display.get_fifo_size(dev, 1);
crtc = intel_get_crtc_for_plane(dev, 1);
if (intel_crtc_active(crtc)) {
- const struct drm_display_mode *adjusted_mode;
int cpp = crtc->fb->bits_per_pixel / 8;
if (IS_GEN2(dev))
cpp = 4;
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
- planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+ planeb_wm = intel_calculate_wm(crtc->mode.clock,
wm_info, fifo_size, cpp,
latency_ns);
if (enabled == NULL)
@@ -1621,11 +1607,9 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
if (HAS_FW_BLC(dev) && enabled) {
/* self-refresh has much higher latency */
static const int sr_latency_ns = 6000;
- const struct drm_display_mode *adjusted_mode =
- &to_intel_crtc(enabled)->config.adjusted_mode;
- int clock = adjusted_mode->crtc_clock;
- int htotal = adjusted_mode->crtc_htotal;
- int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w;
+ int clock = enabled->mode.clock;
+ int htotal = enabled->mode.htotal;
+ int hdisplay = enabled->mode.hdisplay;
int pixel_size = enabled->fb->bits_per_pixel / 8;
unsigned long line_time_us;
int entries;
@@ -1674,12 +1658,10 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
}
}
-static void i830_update_wm(struct drm_crtc *unused_crtc)
+static void i830_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = unused_crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
- const struct drm_display_mode *adjusted_mode;
uint32_t fwater_lo;
int planea_wm;
@@ -1687,9 +1669,7 @@ static void i830_update_wm(struct drm_crtc *unused_crtc)
if (crtc == NULL)
return;
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
- planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
- &i830_wm_info,
+ planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info,
dev_priv->display.get_fifo_size(dev, 0),
4, latency_ns);
fwater_lo = I915_READ(FW_BLC) & ~0xfff;
@@ -1761,7 +1741,6 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane,
int *fbc_wm, int *display_wm, int *cursor_wm)
{
struct drm_crtc *crtc;
- const struct drm_display_mode *adjusted_mode;
unsigned long line_time_us;
int hdisplay, htotal, pixel_size, clock;
int line_count, line_size;
@@ -1774,10 +1753,9 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane,
}
crtc = intel_get_crtc_for_plane(dev, plane);
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
- clock = adjusted_mode->crtc_clock;
- htotal = adjusted_mode->crtc_htotal;
- hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+ hdisplay = crtc->mode.hdisplay;
+ htotal = crtc->mode.htotal;
+ clock = crtc->mode.clock;
pixel_size = crtc->fb->bits_per_pixel / 8;
line_time_us = (htotal * 1000) / clock;
@@ -1807,9 +1785,8 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane,
display, cursor);
}
-static void ironlake_update_wm(struct drm_crtc *crtc)
+static void ironlake_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int fbc_wm, plane_wm, cursor_wm;
unsigned int enabled;
@@ -1891,9 +1868,8 @@ static void ironlake_update_wm(struct drm_crtc *crtc)
*/
}
-static void sandybridge_update_wm(struct drm_crtc *crtc)
+static void sandybridge_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */
u32 val;
@@ -1994,9 +1970,8 @@ static void sandybridge_update_wm(struct drm_crtc *crtc)
cursor_wm);
}
-static void ivybridge_update_wm(struct drm_crtc *crtc)
+static void ivybridge_update_wm(struct drm_device *dev)
{
- struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */
u32 val;
@@ -2123,7 +2098,7 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t pixel_rate;
- pixel_rate = intel_crtc->config.adjusted_mode.crtc_clock;
+ pixel_rate = intel_crtc->config.adjusted_mode.clock;
/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
* adjust the pixel_rate here. */
@@ -2132,8 +2107,8 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev,
uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
uint32_t pfit_size = intel_crtc->config.pch_pfit.size;
- pipe_w = intel_crtc->config.pipe_src_w;
- pipe_h = intel_crtc->config.pipe_src_h;
+ pipe_w = intel_crtc->config.requested_mode.hdisplay;
+ pipe_h = intel_crtc->config.requested_mode.vdisplay;
pfit_w = (pfit_size >> 16) & 0xFFFF;
pfit_h = pfit_size & 0xFFFF;
if (pipe_w < pfit_w)
@@ -2201,18 +2176,27 @@ struct hsw_wm_maximums {
uint16_t fbc;
};
+struct hsw_wm_values {
+ uint32_t wm_pipe[3];
+ uint32_t wm_lp[3];
+ uint32_t wm_lp_spr[3];
+ uint32_t wm_linetime[3];
+ bool enable_fbc_wm;
+};
+
/* used in computing the new watermarks state */
struct intel_wm_config {
unsigned int num_pipes_active;
bool sprites_enabled;
bool sprites_scaled;
+ bool fbc_wm_enabled;
};
/*
* For both WM_PIPE and WM_LP.
* mem_value must be in 0.1us units.
*/
-static uint32_t ilk_compute_pri_wm(const struct hsw_pipe_wm_parameters *params,
+static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params,
uint32_t mem_value,
bool is_lp)
{
@@ -2241,7 +2225,7 @@ static uint32_t ilk_compute_pri_wm(const struct hsw_pipe_wm_parameters *params,
* For both WM_PIPE and WM_LP.
* mem_value must be in 0.1us units.
*/
-static uint32_t ilk_compute_spr_wm(const struct hsw_pipe_wm_parameters *params,
+static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params,
uint32_t mem_value)
{
uint32_t method1, method2;
@@ -2264,7 +2248,7 @@ static uint32_t ilk_compute_spr_wm(const struct hsw_pipe_wm_parameters *params,
* For both WM_PIPE and WM_LP.
* mem_value must be in 0.1us units.
*/
-static uint32_t ilk_compute_cur_wm(const struct hsw_pipe_wm_parameters *params,
+static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params,
uint32_t mem_value)
{
if (!params->active || !params->cur.enabled)
@@ -2278,7 +2262,7 @@ static uint32_t ilk_compute_cur_wm(const struct hsw_pipe_wm_parameters *params,
}
/* Only for WM_LP. */
-static uint32_t ilk_compute_fbc_wm(const struct hsw_pipe_wm_parameters *params,
+static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params,
uint32_t pri_val)
{
if (!params->active || !params->pri.enabled)
@@ -2291,9 +2275,7 @@ static uint32_t ilk_compute_fbc_wm(const struct hsw_pipe_wm_parameters *params,
static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
{
- if (INTEL_INFO(dev)->gen >= 8)
- return 3072;
- else if (INTEL_INFO(dev)->gen >= 7)
+ if (INTEL_INFO(dev)->gen >= 7)
return 768;
else
return 512;
@@ -2338,9 +2320,7 @@ static unsigned int ilk_plane_wm_max(const struct drm_device *dev,
}
/* clamp to max that the registers can hold */
- if (INTEL_INFO(dev)->gen >= 8)
- max = level == 0 ? 255 : 2047;
- else if (INTEL_INFO(dev)->gen >= 7)
+ if (INTEL_INFO(dev)->gen >= 7)
/* IVB/HSW primary/sprite plane watermarks */
max = level == 0 ? 127 : 1023;
else if (!is_sprite)
@@ -2370,30 +2350,27 @@ static unsigned int ilk_cursor_wm_max(const struct drm_device *dev,
}
/* Calculate the maximum FBC watermark */
-static unsigned int ilk_fbc_wm_max(struct drm_device *dev)
+static unsigned int ilk_fbc_wm_max(void)
{
/* max that registers can hold */
- if (INTEL_INFO(dev)->gen >= 8)
- return 31;
- else
- return 15;
+ return 15;
}
-static void ilk_compute_wm_maximums(struct drm_device *dev,
- int level,
- const struct intel_wm_config *config,
- enum intel_ddb_partitioning ddb_partitioning,
- struct hsw_wm_maximums *max)
+static void ilk_wm_max(struct drm_device *dev,
+ int level,
+ const struct intel_wm_config *config,
+ enum intel_ddb_partitioning ddb_partitioning,
+ struct hsw_wm_maximums *max)
{
max->pri = ilk_plane_wm_max(dev, level, config, ddb_partitioning, false);
max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true);
max->cur = ilk_cursor_wm_max(dev, level, config);
- max->fbc = ilk_fbc_wm_max(dev);
+ max->fbc = ilk_fbc_wm_max();
}
-static bool ilk_validate_wm_level(int level,
- const struct hsw_wm_maximums *max,
- struct intel_wm_level *result)
+static bool ilk_check_wm(int level,
+ const struct hsw_wm_maximums *max,
+ struct intel_wm_level *result)
{
bool ret;
@@ -2429,12 +2406,14 @@ static bool ilk_validate_wm_level(int level,
result->enable = true;
}
+ DRM_DEBUG_KMS("WM%d: %sabled\n", level, result->enable ? "en" : "dis");
+
return ret;
}
static void ilk_compute_wm_level(struct drm_i915_private *dev_priv,
int level,
- const struct hsw_pipe_wm_parameters *p,
+ struct hsw_pipe_wm_parameters *p,
struct intel_wm_level *result)
{
uint16_t pri_latency = dev_priv->wm.pri_latency[level];
@@ -2455,6 +2434,55 @@ static void ilk_compute_wm_level(struct drm_i915_private *dev_priv,
result->enable = true;
}
+static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv,
+ int level, struct hsw_wm_maximums *max,
+ struct hsw_pipe_wm_parameters *params,
+ struct intel_wm_level *result)
+{
+ enum pipe pipe;
+ struct intel_wm_level res[3];
+
+ for (pipe = PIPE_A; pipe <= PIPE_C; pipe++)
+ ilk_compute_wm_level(dev_priv, level, &params[pipe], &res[pipe]);
+
+ result->pri_val = max3(res[0].pri_val, res[1].pri_val, res[2].pri_val);
+ result->spr_val = max3(res[0].spr_val, res[1].spr_val, res[2].spr_val);
+ result->cur_val = max3(res[0].cur_val, res[1].cur_val, res[2].cur_val);
+ result->fbc_val = max3(res[0].fbc_val, res[1].fbc_val, res[2].fbc_val);
+ result->enable = true;
+
+ return ilk_check_wm(level, max, result);
+}
+
+static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv,
+ enum pipe pipe,
+ struct hsw_pipe_wm_parameters *params)
+{
+ uint32_t pri_val, cur_val, spr_val;
+ /* WM0 latency values stored in 0.1us units */
+ uint16_t pri_latency = dev_priv->wm.pri_latency[0];
+ uint16_t spr_latency = dev_priv->wm.spr_latency[0];
+ uint16_t cur_latency = dev_priv->wm.cur_latency[0];
+
+ pri_val = ilk_compute_pri_wm(params, pri_latency, false);
+ spr_val = ilk_compute_spr_wm(params, spr_latency);
+ cur_val = ilk_compute_cur_wm(params, cur_latency);
+
+ WARN(pri_val > 127,
+ "Primary WM error, mode not supported for pipe %c\n",
+ pipe_name(pipe));
+ WARN(spr_val > 127,
+ "Sprite WM error, mode not supported for pipe %c\n",
+ pipe_name(pipe));
+ WARN(cur_val > 63,
+ "Cursor WM error, mode not supported for pipe %c\n",
+ pipe_name(pipe));
+
+ return (pri_val << WM0_PIPE_PLANE_SHIFT) |
+ (spr_val << WM0_PIPE_SPRITE_SHIFT) |
+ cur_val;
+}
+
static uint32_t
hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
{
@@ -2469,9 +2497,8 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
/* The WM are computed with base on how long it takes to fill a single
* row at the given clock rate, multiplied by 8.
* */
- linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
- mode->crtc_clock);
- ips_linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
+ linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, mode->clock);
+ ips_linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8,
intel_ddi_get_cdclk_freq(dev_priv));
return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
@@ -2527,22 +2554,19 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5])
wm[3] *= 2;
}
-static int ilk_wm_max_level(const struct drm_device *dev)
+static void intel_print_wm_latency(struct drm_device *dev,
+ const char *name,
+ const uint16_t wm[5])
{
+ int level, max_level;
+
/* how many WM levels are we expecting */
if (IS_HASWELL(dev))
- return 4;
+ max_level = 4;
else if (INTEL_INFO(dev)->gen >= 6)
- return 3;
+ max_level = 3;
else
- return 2;
-}
-
-static void intel_print_wm_latency(struct drm_device *dev,
- const char *name,
- const uint16_t wm[5])
-{
- int level, max_level = ilk_wm_max_level(dev);
+ max_level = 2;
for (level = 0; level <= max_level; level++) {
unsigned int latency = wm[level];
@@ -2582,321 +2606,218 @@ static void intel_setup_wm_latency(struct drm_device *dev)
intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
}
-static void hsw_compute_wm_parameters(struct drm_crtc *crtc,
- struct hsw_pipe_wm_parameters *p,
- struct intel_wm_config *config)
+static void hsw_compute_wm_parameters(struct drm_device *dev,
+ struct hsw_pipe_wm_parameters *params,
+ struct hsw_wm_maximums *lp_max_1_2,
+ struct hsw_wm_maximums *lp_max_5_6)
{
- struct drm_device *dev = crtc->dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
+ struct drm_crtc *crtc;
struct drm_plane *plane;
+ enum pipe pipe;
+ struct intel_wm_config config = {};
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct hsw_pipe_wm_parameters *p;
+
+ pipe = intel_crtc->pipe;
+ p = &params[pipe];
+
+ p->active = intel_crtc_active(crtc);
+ if (!p->active)
+ continue;
+
+ config.num_pipes_active++;
- p->active = intel_crtc_active(crtc);
- if (p->active) {
p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal;
p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8;
p->cur.bytes_per_pixel = 4;
- p->pri.horiz_pixels = intel_crtc->config.pipe_src_w;
+ p->pri.horiz_pixels =
+ intel_crtc->config.requested_mode.hdisplay;
p->cur.horiz_pixels = 64;
/* TODO: for now, assume primary and cursor planes are always enabled. */
p->pri.enabled = true;
p->cur.enabled = true;
}
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- config->num_pipes_active += intel_crtc_active(crtc);
-
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct hsw_pipe_wm_parameters *p;
- if (intel_plane->pipe == pipe)
- p->spr = intel_plane->wm;
+ pipe = intel_plane->pipe;
+ p = &params[pipe];
- config->sprites_enabled |= intel_plane->wm.enabled;
- config->sprites_scaled |= intel_plane->wm.scaled;
- }
-}
-
-/* Compute new watermarks for the pipe */
-static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
- const struct hsw_pipe_wm_parameters *params,
- struct intel_pipe_wm *pipe_wm)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int level, max_level = ilk_wm_max_level(dev);
- /* LP0 watermark maximums depend on this pipe alone */
- struct intel_wm_config config = {
- .num_pipes_active = 1,
- .sprites_enabled = params->spr.enabled,
- .sprites_scaled = params->spr.scaled,
- };
- struct hsw_wm_maximums max;
-
- /* LP0 watermarks always use 1/2 DDB partitioning */
- ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
+ p->spr = intel_plane->wm;
- for (level = 0; level <= max_level; level++)
- ilk_compute_wm_level(dev_priv, level, params,
- &pipe_wm->wm[level]);
+ config.sprites_enabled |= p->spr.enabled;
+ config.sprites_scaled |= p->spr.scaled;
+ }
- pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
+ ilk_wm_max(dev, 1, &config, INTEL_DDB_PART_1_2, lp_max_1_2);
- /* At least LP0 must be valid */
- return ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]);
+ /* 5/6 split only in single pipe config on IVB+ */
+ if (INTEL_INFO(dev)->gen >= 7 && config.num_pipes_active <= 1)
+ ilk_wm_max(dev, 1, &config, INTEL_DDB_PART_5_6, lp_max_5_6);
+ else
+ *lp_max_5_6 = *lp_max_1_2;
}
-/*
- * Merge the watermarks from all active pipes for a specific level.
- */
-static void ilk_merge_wm_level(struct drm_device *dev,
- int level,
- struct intel_wm_level *ret_wm)
+static void hsw_compute_wm_results(struct drm_device *dev,
+ struct hsw_pipe_wm_parameters *params,
+ struct hsw_wm_maximums *lp_maximums,
+ struct hsw_wm_values *results)
{
- const struct intel_crtc *intel_crtc;
-
- list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) {
- const struct intel_wm_level *wm =
- &intel_crtc->wm.active.wm[level];
-
- if (!wm->enable)
- return;
-
- ret_wm->pri_val = max(ret_wm->pri_val, wm->pri_val);
- ret_wm->spr_val = max(ret_wm->spr_val, wm->spr_val);
- ret_wm->cur_val = max(ret_wm->cur_val, wm->cur_val);
- ret_wm->fbc_val = max(ret_wm->fbc_val, wm->fbc_val);
- }
-
- ret_wm->enable = true;
-}
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc;
+ struct intel_wm_level lp_results[4] = {};
+ enum pipe pipe;
+ int level, max_level, wm_lp;
-/*
- * Merge all low power watermarks for all active pipes.
- */
-static void ilk_wm_merge(struct drm_device *dev,
- const struct hsw_wm_maximums *max,
- struct intel_pipe_wm *merged)
-{
- int level, max_level = ilk_wm_max_level(dev);
+ for (level = 1; level <= 4; level++)
+ if (!hsw_compute_lp_wm(dev_priv, level,
+ lp_maximums, params,
+ &lp_results[level - 1]))
+ break;
+ max_level = level - 1;
- merged->fbc_wm_enabled = true;
+ memset(results, 0, sizeof(*results));
- /* merge each WM1+ level */
+ /* The spec says it is preferred to disable FBC WMs instead of disabling
+ * a WM level. */
+ results->enable_fbc_wm = true;
for (level = 1; level <= max_level; level++) {
- struct intel_wm_level *wm = &merged->wm[level];
-
- ilk_merge_wm_level(dev, level, wm);
-
- if (!ilk_validate_wm_level(level, max, wm))
- break;
-
- /*
- * The spec says it is preferred to disable
- * FBC WMs instead of disabling a WM level.
- */
- if (wm->fbc_val > max->fbc) {
- merged->fbc_wm_enabled = false;
- wm->fbc_val = 0;
+ if (lp_results[level - 1].fbc_val > lp_maximums->fbc) {
+ results->enable_fbc_wm = false;
+ lp_results[level - 1].fbc_val = 0;
}
}
-}
-static int ilk_wm_lp_to_level(int wm_lp, const struct intel_pipe_wm *pipe_wm)
-{
- /* LP1,LP2,LP3 levels are either 1,2,3 or 1,3,4 */
- return wm_lp + (wm_lp >= 2 && pipe_wm->wm[4].enable);
-}
-
-static void hsw_compute_wm_results(struct drm_device *dev,
- const struct intel_pipe_wm *merged,
- enum intel_ddb_partitioning partitioning,
- struct hsw_wm_values *results)
-{
- struct intel_crtc *intel_crtc;
- int level, wm_lp;
-
- results->enable_fbc_wm = merged->fbc_wm_enabled;
- results->partitioning = partitioning;
-
- /* LP1+ register values */
for (wm_lp = 1; wm_lp <= 3; wm_lp++) {
const struct intel_wm_level *r;
- level = ilk_wm_lp_to_level(wm_lp, merged);
-
- r = &merged->wm[level];
- if (!r->enable)
+ level = (max_level == 4 && wm_lp > 1) ? wm_lp + 1 : wm_lp;
+ if (level > max_level)
break;
- results->wm_lp[wm_lp - 1] = WM3_LP_EN |
- ((level * 2) << WM1_LP_LATENCY_SHIFT) |
- (r->pri_val << WM1_LP_SR_SHIFT) |
- r->cur_val;
-
- if (INTEL_INFO(dev)->gen >= 8)
- results->wm_lp[wm_lp - 1] |=
- r->fbc_val << WM1_LP_FBC_SHIFT_BDW;
- else
- results->wm_lp[wm_lp - 1] |=
- r->fbc_val << WM1_LP_FBC_SHIFT;
-
+ r = &lp_results[level - 1];
+ results->wm_lp[wm_lp - 1] = HSW_WM_LP_VAL(level * 2,
+ r->fbc_val,
+ r->pri_val,
+ r->cur_val);
results->wm_lp_spr[wm_lp - 1] = r->spr_val;
}
- /* LP0 register values */
- list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) {
- enum pipe pipe = intel_crtc->pipe;
- const struct intel_wm_level *r =
- &intel_crtc->wm.active.wm[0];
-
- if (WARN_ON(!r->enable))
- continue;
-
- results->wm_linetime[pipe] = intel_crtc->wm.active.linetime;
+ for_each_pipe(pipe)
+ results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, pipe,
+ &params[pipe]);
- results->wm_pipe[pipe] =
- (r->pri_val << WM0_PIPE_PLANE_SHIFT) |
- (r->spr_val << WM0_PIPE_SPRITE_SHIFT) |
- r->cur_val;
+ for_each_pipe(pipe) {
+ crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+ results->wm_linetime[pipe] = hsw_compute_linetime_wm(dev, crtc);
}
}
/* Find the result with the highest level enabled. Check for enable_fbc_wm in
* case both are at the same level. Prefer r1 in case they're the same. */
-static struct intel_pipe_wm *hsw_find_best_result(struct drm_device *dev,
- struct intel_pipe_wm *r1,
- struct intel_pipe_wm *r2)
+static struct hsw_wm_values *hsw_find_best_result(struct hsw_wm_values *r1,
+ struct hsw_wm_values *r2)
{
- int level, max_level = ilk_wm_max_level(dev);
- int level1 = 0, level2 = 0;
+ int i, val_r1 = 0, val_r2 = 0;
- for (level = 1; level <= max_level; level++) {
- if (r1->wm[level].enable)
- level1 = level;
- if (r2->wm[level].enable)
- level2 = level;
+ for (i = 0; i < 3; i++) {
+ if (r1->wm_lp[i] & WM3_LP_EN)
+ val_r1 = r1->wm_lp[i] & WM1_LP_LATENCY_MASK;
+ if (r2->wm_lp[i] & WM3_LP_EN)
+ val_r2 = r2->wm_lp[i] & WM1_LP_LATENCY_MASK;
}
- if (level1 == level2) {
- if (r2->fbc_wm_enabled && !r1->fbc_wm_enabled)
+ if (val_r1 == val_r2) {
+ if (r2->enable_fbc_wm && !r1->enable_fbc_wm)
return r2;
else
return r1;
- } else if (level1 > level2) {
+ } else if (val_r1 > val_r2) {
return r1;
} else {
return r2;
}
}
-/* dirty bits used to track which watermarks need changes */
-#define WM_DIRTY_PIPE(pipe) (1 << (pipe))
-#define WM_DIRTY_LINETIME(pipe) (1 << (8 + (pipe)))
-#define WM_DIRTY_LP(wm_lp) (1 << (15 + (wm_lp)))
-#define WM_DIRTY_LP_ALL (WM_DIRTY_LP(1) | WM_DIRTY_LP(2) | WM_DIRTY_LP(3))
-#define WM_DIRTY_FBC (1 << 24)
-#define WM_DIRTY_DDB (1 << 25)
-
-static unsigned int ilk_compute_wm_dirty(struct drm_device *dev,
- const struct hsw_wm_values *old,
- const struct hsw_wm_values *new)
-{
- unsigned int dirty = 0;
- enum pipe pipe;
- int wm_lp;
-
- for_each_pipe(pipe) {
- if (old->wm_linetime[pipe] != new->wm_linetime[pipe]) {
- dirty |= WM_DIRTY_LINETIME(pipe);
- /* Must disable LP1+ watermarks too */
- dirty |= WM_DIRTY_LP_ALL;
- }
-
- if (old->wm_pipe[pipe] != new->wm_pipe[pipe]) {
- dirty |= WM_DIRTY_PIPE(pipe);
- /* Must disable LP1+ watermarks too */
- dirty |= WM_DIRTY_LP_ALL;
- }
- }
-
- if (old->enable_fbc_wm != new->enable_fbc_wm) {
- dirty |= WM_DIRTY_FBC;
- /* Must disable LP1+ watermarks too */
- dirty |= WM_DIRTY_LP_ALL;
- }
-
- if (old->partitioning != new->partitioning) {
- dirty |= WM_DIRTY_DDB;
- /* Must disable LP1+ watermarks too */
- dirty |= WM_DIRTY_LP_ALL;
- }
-
- /* LP1+ watermarks already deemed dirty, no need to continue */
- if (dirty & WM_DIRTY_LP_ALL)
- return dirty;
-
- /* Find the lowest numbered LP1+ watermark in need of an update... */
- for (wm_lp = 1; wm_lp <= 3; wm_lp++) {
- if (old->wm_lp[wm_lp - 1] != new->wm_lp[wm_lp - 1] ||
- old->wm_lp_spr[wm_lp - 1] != new->wm_lp_spr[wm_lp - 1])
- break;
- }
-
- /* ...and mark it and all higher numbered LP1+ watermarks as dirty */
- for (; wm_lp <= 3; wm_lp++)
- dirty |= WM_DIRTY_LP(wm_lp);
-
- return dirty;
-}
-
/*
* The spec says we shouldn't write when we don't need, because every write
* causes WMs to be re-evaluated, expending some power.
*/
static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
- struct hsw_wm_values *results)
+ struct hsw_wm_values *results,
+ enum intel_ddb_partitioning partitioning)
{
- struct hsw_wm_values *previous = &dev_priv->wm.hw;
- unsigned int dirty;
+ struct hsw_wm_values previous;
uint32_t val;
-
- dirty = ilk_compute_wm_dirty(dev_priv->dev, previous, results);
- if (!dirty)
+ enum intel_ddb_partitioning prev_partitioning;
+ bool prev_enable_fbc_wm;
+
+ previous.wm_pipe[0] = I915_READ(WM0_PIPEA_ILK);
+ previous.wm_pipe[1] = I915_READ(WM0_PIPEB_ILK);
+ previous.wm_pipe[2] = I915_READ(WM0_PIPEC_IVB);
+ previous.wm_lp[0] = I915_READ(WM1_LP_ILK);
+ previous.wm_lp[1] = I915_READ(WM2_LP_ILK);
+ previous.wm_lp[2] = I915_READ(WM3_LP_ILK);
+ previous.wm_lp_spr[0] = I915_READ(WM1S_LP_ILK);
+ previous.wm_lp_spr[1] = I915_READ(WM2S_LP_IVB);
+ previous.wm_lp_spr[2] = I915_READ(WM3S_LP_IVB);
+ previous.wm_linetime[0] = I915_READ(PIPE_WM_LINETIME(PIPE_A));
+ previous.wm_linetime[1] = I915_READ(PIPE_WM_LINETIME(PIPE_B));
+ previous.wm_linetime[2] = I915_READ(PIPE_WM_LINETIME(PIPE_C));
+
+ prev_partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ?
+ INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
+
+ prev_enable_fbc_wm = !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS);
+
+ if (memcmp(results->wm_pipe, previous.wm_pipe,
+ sizeof(results->wm_pipe)) == 0 &&
+ memcmp(results->wm_lp, previous.wm_lp,
+ sizeof(results->wm_lp)) == 0 &&
+ memcmp(results->wm_lp_spr, previous.wm_lp_spr,
+ sizeof(results->wm_lp_spr)) == 0 &&
+ memcmp(results->wm_linetime, previous.wm_linetime,
+ sizeof(results->wm_linetime)) == 0 &&
+ partitioning == prev_partitioning &&
+ results->enable_fbc_wm == prev_enable_fbc_wm)
return;
- if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] != 0)
+ if (previous.wm_lp[2] != 0)
I915_WRITE(WM3_LP_ILK, 0);
- if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] != 0)
+ if (previous.wm_lp[1] != 0)
I915_WRITE(WM2_LP_ILK, 0);
- if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] != 0)
+ if (previous.wm_lp[0] != 0)
I915_WRITE(WM1_LP_ILK, 0);
- if (dirty & WM_DIRTY_PIPE(PIPE_A))
+ if (previous.wm_pipe[0] != results->wm_pipe[0])
I915_WRITE(WM0_PIPEA_ILK, results->wm_pipe[0]);
- if (dirty & WM_DIRTY_PIPE(PIPE_B))
+ if (previous.wm_pipe[1] != results->wm_pipe[1])
I915_WRITE(WM0_PIPEB_ILK, results->wm_pipe[1]);
- if (dirty & WM_DIRTY_PIPE(PIPE_C))
+ if (previous.wm_pipe[2] != results->wm_pipe[2])
I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]);
- if (dirty & WM_DIRTY_LINETIME(PIPE_A))
+ if (previous.wm_linetime[0] != results->wm_linetime[0])
I915_WRITE(PIPE_WM_LINETIME(PIPE_A), results->wm_linetime[0]);
- if (dirty & WM_DIRTY_LINETIME(PIPE_B))
+ if (previous.wm_linetime[1] != results->wm_linetime[1])
I915_WRITE(PIPE_WM_LINETIME(PIPE_B), results->wm_linetime[1]);
- if (dirty & WM_DIRTY_LINETIME(PIPE_C))
+ if (previous.wm_linetime[2] != results->wm_linetime[2])
I915_WRITE(PIPE_WM_LINETIME(PIPE_C), results->wm_linetime[2]);
- if (dirty & WM_DIRTY_DDB) {
+ if (prev_partitioning != partitioning) {
val = I915_READ(WM_MISC);
- if (results->partitioning == INTEL_DDB_PART_1_2)
+ if (partitioning == INTEL_DDB_PART_1_2)
val &= ~WM_MISC_DATA_PARTITION_5_6;
else
val |= WM_MISC_DATA_PARTITION_5_6;
I915_WRITE(WM_MISC, val);
}
- if (dirty & WM_DIRTY_FBC) {
+ if (prev_enable_fbc_wm != results->enable_fbc_wm) {
val = I915_READ(DISP_ARB_CTL);
if (results->enable_fbc_wm)
val &= ~DISP_FBC_WM_DIS;
@@ -2905,65 +2826,45 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
I915_WRITE(DISP_ARB_CTL, val);
}
- if (dirty & WM_DIRTY_LP(1) && previous->wm_lp_spr[0] != results->wm_lp_spr[0])
+ if (previous.wm_lp_spr[0] != results->wm_lp_spr[0])
I915_WRITE(WM1S_LP_ILK, results->wm_lp_spr[0]);
- if (dirty & WM_DIRTY_LP(2) && previous->wm_lp_spr[1] != results->wm_lp_spr[1])
+ if (previous.wm_lp_spr[1] != results->wm_lp_spr[1])
I915_WRITE(WM2S_LP_IVB, results->wm_lp_spr[1]);
- if (dirty & WM_DIRTY_LP(3) && previous->wm_lp_spr[2] != results->wm_lp_spr[2])
+ if (previous.wm_lp_spr[2] != results->wm_lp_spr[2])
I915_WRITE(WM3S_LP_IVB, results->wm_lp_spr[2]);
- if (dirty & WM_DIRTY_LP(1) && results->wm_lp[0] != 0)
+ if (results->wm_lp[0] != 0)
I915_WRITE(WM1_LP_ILK, results->wm_lp[0]);
- if (dirty & WM_DIRTY_LP(2) && results->wm_lp[1] != 0)
+ if (results->wm_lp[1] != 0)
I915_WRITE(WM2_LP_ILK, results->wm_lp[1]);
- if (dirty & WM_DIRTY_LP(3) && results->wm_lp[2] != 0)
+ if (results->wm_lp[2] != 0)
I915_WRITE(WM3_LP_ILK, results->wm_lp[2]);
-
- dev_priv->wm.hw = *results;
}
-static void haswell_update_wm(struct drm_crtc *crtc)
+static void haswell_update_wm(struct drm_device *dev)
{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct hsw_wm_maximums max;
- struct hsw_pipe_wm_parameters params = {};
- struct hsw_wm_values results = {};
+ struct hsw_wm_maximums lp_max_1_2, lp_max_5_6;
+ struct hsw_pipe_wm_parameters params[3];
+ struct hsw_wm_values results_1_2, results_5_6, *best_results;
enum intel_ddb_partitioning partitioning;
- struct intel_pipe_wm pipe_wm = {};
- struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
- struct intel_wm_config config = {};
- hsw_compute_wm_parameters(crtc, &params, &config);
-
- intel_compute_pipe_wm(crtc, &params, &pipe_wm);
-
- if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
- return;
+ hsw_compute_wm_parameters(dev, params, &lp_max_1_2, &lp_max_5_6);
- intel_crtc->wm.active = pipe_wm;
-
- ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max);
- ilk_wm_merge(dev, &max, &lp_wm_1_2);
-
- /* 5/6 split only in single pipe config on IVB+ */
- if (INTEL_INFO(dev)->gen >= 7 &&
- config.num_pipes_active == 1 && config.sprites_enabled) {
- ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max);
- ilk_wm_merge(dev, &max, &lp_wm_5_6);
-
- best_lp_wm = hsw_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6);
+ hsw_compute_wm_results(dev, params,
+ &lp_max_1_2, &results_1_2);
+ if (lp_max_1_2.pri != lp_max_5_6.pri) {
+ hsw_compute_wm_results(dev, params,
+ &lp_max_5_6, &results_5_6);
+ best_results = hsw_find_best_result(&results_1_2, &results_5_6);
} else {
- best_lp_wm = &lp_wm_1_2;
+ best_results = &results_1_2;
}
- partitioning = (best_lp_wm == &lp_wm_1_2) ?
+ partitioning = (best_results == &results_1_2) ?
INTEL_DDB_PART_1_2 : INTEL_DDB_PART_5_6;
- hsw_compute_wm_results(dev, best_lp_wm, partitioning, &results);
-
- hsw_write_wm_values(dev_priv, &results);
+ hsw_write_wm_values(dev_priv, best_results, partitioning);
}
static void haswell_update_sprite_wm(struct drm_plane *plane,
@@ -2978,7 +2879,7 @@ static void haswell_update_sprite_wm(struct drm_plane *plane,
intel_plane->wm.horiz_pixels = sprite_width;
intel_plane->wm.bytes_per_pixel = pixel_size;
- haswell_update_wm(crtc);
+ haswell_update_wm(plane->dev);
}
static bool
@@ -2997,7 +2898,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane,
return false;
}
- clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
+ clock = crtc->mode.clock;
/* Use the small buffer method to calculate the sprite watermark */
entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
@@ -3032,7 +2933,7 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane,
}
crtc = intel_get_crtc_for_plane(dev, plane);
- clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
+ clock = crtc->mode.clock;
if (!clock) {
*sprite_wm = 0;
return false;
@@ -3143,74 +3044,6 @@ static void sandybridge_update_sprite_wm(struct drm_plane *plane,
I915_WRITE(WM3S_LP_IVB, sprite_wm);
}
-static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct hsw_wm_values *hw = &dev_priv->wm.hw;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_pipe_wm *active = &intel_crtc->wm.active;
- enum pipe pipe = intel_crtc->pipe;
- static const unsigned int wm0_pipe_reg[] = {
- [PIPE_A] = WM0_PIPEA_ILK,
- [PIPE_B] = WM0_PIPEB_ILK,
- [PIPE_C] = WM0_PIPEC_IVB,
- };
-
- hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]);
- hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
-
- if (intel_crtc_active(crtc)) {
- u32 tmp = hw->wm_pipe[pipe];
-
- /*
- * For active pipes LP0 watermark is marked as
- * enabled, and LP1+ watermaks as disabled since
- * we can't really reverse compute them in case
- * multiple pipes are active.
- */
- active->wm[0].enable = true;
- active->wm[0].pri_val = (tmp & WM0_PIPE_PLANE_MASK) >> WM0_PIPE_PLANE_SHIFT;
- active->wm[0].spr_val = (tmp & WM0_PIPE_SPRITE_MASK) >> WM0_PIPE_SPRITE_SHIFT;
- active->wm[0].cur_val = tmp & WM0_PIPE_CURSOR_MASK;
- active->linetime = hw->wm_linetime[pipe];
- } else {
- int level, max_level = ilk_wm_max_level(dev);
-
- /*
- * For inactive pipes, all watermark levels
- * should be marked as enabled but zeroed,
- * which is what we'd compute them to.
- */
- for (level = 0; level <= max_level; level++)
- active->wm[level].enable = true;
- }
-}
-
-void ilk_wm_get_hw_state(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct hsw_wm_values *hw = &dev_priv->wm.hw;
- struct drm_crtc *crtc;
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- ilk_pipe_wm_get_hw_state(crtc);
-
- hw->wm_lp[0] = I915_READ(WM1_LP_ILK);
- hw->wm_lp[1] = I915_READ(WM2_LP_ILK);
- hw->wm_lp[2] = I915_READ(WM3_LP_ILK);
-
- hw->wm_lp_spr[0] = I915_READ(WM1S_LP_ILK);
- hw->wm_lp_spr[1] = I915_READ(WM2S_LP_IVB);
- hw->wm_lp_spr[2] = I915_READ(WM3S_LP_IVB);
-
- hw->partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ?
- INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
-
- hw->enable_fbc_wm =
- !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS);
-}
-
/**
* intel_update_watermarks - update FIFO watermark values based on current modes
*
@@ -3243,12 +3076,12 @@ void ilk_wm_get_hw_state(struct drm_device *dev)
* We don't use the sprite, so we can ignore that. And on Crestline we have
* to set the non-SR watermarks to 8.
*/
-void intel_update_watermarks(struct drm_crtc *crtc)
+void intel_update_watermarks(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (dev_priv->display.update_wm)
- dev_priv->display.update_wm(crtc);
+ dev_priv->display.update_wm(dev);
}
void intel_update_sprite_watermarks(struct drm_plane *plane,
@@ -3454,98 +3287,6 @@ static u32 gen6_rps_limits(struct drm_i915_private *dev_priv, u8 *val)
return limits;
}
-static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
-{
- int new_power;
-
- new_power = dev_priv->rps.power;
- switch (dev_priv->rps.power) {
- case LOW_POWER:
- if (val > dev_priv->rps.rpe_delay + 1 && val > dev_priv->rps.cur_delay)
- new_power = BETWEEN;
- break;
-
- case BETWEEN:
- if (val <= dev_priv->rps.rpe_delay && val < dev_priv->rps.cur_delay)
- new_power = LOW_POWER;
- else if (val >= dev_priv->rps.rp0_delay && val > dev_priv->rps.cur_delay)
- new_power = HIGH_POWER;
- break;
-
- case HIGH_POWER:
- if (val < (dev_priv->rps.rp1_delay + dev_priv->rps.rp0_delay) >> 1 && val < dev_priv->rps.cur_delay)
- new_power = BETWEEN;
- break;
- }
- /* Max/min bins are special */
- if (val == dev_priv->rps.min_delay)
- new_power = LOW_POWER;
- if (val == dev_priv->rps.max_delay)
- new_power = HIGH_POWER;
- if (new_power == dev_priv->rps.power)
- return;
-
- /* Note the units here are not exactly 1us, but 1280ns. */
- switch (new_power) {
- case LOW_POWER:
- /* Upclock if more than 95% busy over 16ms */
- I915_WRITE(GEN6_RP_UP_EI, 12500);
- I915_WRITE(GEN6_RP_UP_THRESHOLD, 11800);
-
- /* Downclock if less than 85% busy over 32ms */
- I915_WRITE(GEN6_RP_DOWN_EI, 25000);
- I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 21250);
-
- I915_WRITE(GEN6_RP_CONTROL,
- GEN6_RP_MEDIA_TURBO |
- GEN6_RP_MEDIA_HW_NORMAL_MODE |
- GEN6_RP_MEDIA_IS_GFX |
- GEN6_RP_ENABLE |
- GEN6_RP_UP_BUSY_AVG |
- GEN6_RP_DOWN_IDLE_AVG);
- break;
-
- case BETWEEN:
- /* Upclock if more than 90% busy over 13ms */
- I915_WRITE(GEN6_RP_UP_EI, 10250);
- I915_WRITE(GEN6_RP_UP_THRESHOLD, 9225);
-
- /* Downclock if less than 75% busy over 32ms */
- I915_WRITE(GEN6_RP_DOWN_EI, 25000);
- I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 18750);
-
- I915_WRITE(GEN6_RP_CONTROL,
- GEN6_RP_MEDIA_TURBO |
- GEN6_RP_MEDIA_HW_NORMAL_MODE |
- GEN6_RP_MEDIA_IS_GFX |
- GEN6_RP_ENABLE |
- GEN6_RP_UP_BUSY_AVG |
- GEN6_RP_DOWN_IDLE_AVG);
- break;
-
- case HIGH_POWER:
- /* Upclock if more than 85% busy over 10ms */
- I915_WRITE(GEN6_RP_UP_EI, 8000);
- I915_WRITE(GEN6_RP_UP_THRESHOLD, 6800);
-
- /* Downclock if less than 60% busy over 32ms */
- I915_WRITE(GEN6_RP_DOWN_EI, 25000);
- I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 15000);
-
- I915_WRITE(GEN6_RP_CONTROL,
- GEN6_RP_MEDIA_TURBO |
- GEN6_RP_MEDIA_HW_NORMAL_MODE |
- GEN6_RP_MEDIA_IS_GFX |
- GEN6_RP_ENABLE |
- GEN6_RP_UP_BUSY_AVG |
- GEN6_RP_DOWN_IDLE_AVG);
- break;
- }
-
- dev_priv->rps.power = new_power;
- dev_priv->rps.last_adj = 0;
-}
-
void gen6_set_rps(struct drm_device *dev, u8 val)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3558,8 +3299,6 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
if (val == dev_priv->rps.cur_delay)
return;
- gen6_set_rps_thresholds(dev_priv, val);
-
if (IS_HASWELL(dev))
I915_WRITE(GEN6_RPNSWREQ,
HSW_FREQUENCY(val));
@@ -3581,32 +3320,6 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
trace_intel_gpu_freq_change(val * 50);
}
-void gen6_rps_idle(struct drm_i915_private *dev_priv)
-{
- mutex_lock(&dev_priv->rps.hw_lock);
- if (dev_priv->rps.enabled) {
- if (dev_priv->info->is_valleyview)
- valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
- else
- gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
- dev_priv->rps.last_adj = 0;
- }
- mutex_unlock(&dev_priv->rps.hw_lock);
-}
-
-void gen6_rps_boost(struct drm_i915_private *dev_priv)
-{
- mutex_lock(&dev_priv->rps.hw_lock);
- if (dev_priv->rps.enabled) {
- if (dev_priv->info->is_valleyview)
- valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_delay);
- else
- gen6_set_rps(dev_priv->dev, dev_priv->rps.max_delay);
- dev_priv->rps.last_adj = 0;
- }
- mutex_unlock(&dev_priv->rps.hw_lock);
-}
-
/*
* Wait until the previous freq change has completed,
* or the timeout elapsed, and then update our notion
@@ -3702,20 +3415,6 @@ static void valleyview_disable_rps(struct drm_device *dev)
}
}
-static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
-{
- if (IS_GEN6(dev))
- DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n");
-
- if (IS_HASWELL(dev))
- DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
-
- DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
- (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
- (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
- (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off");
-}
-
int intel_enable_rc6(const struct drm_device *dev)
{
/* No RC6 before Ironlake */
@@ -3730,13 +3429,18 @@ int intel_enable_rc6(const struct drm_device *dev)
if (INTEL_INFO(dev)->gen == 5)
return 0;
- if (IS_HASWELL(dev))
+ if (IS_HASWELL(dev)) {
+ DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
return INTEL_RC6_ENABLE;
+ }
/* snb/ivb have more than one rc6 state. */
- if (INTEL_INFO(dev)->gen == 6)
+ if (INTEL_INFO(dev)->gen == 6) {
+ DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n");
return INTEL_RC6_ENABLE;
+ }
+ DRM_DEBUG_DRIVER("RC6 and deep RC6 enabled\n");
return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
}
@@ -3763,78 +3467,6 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev)
I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs);
}
-static void gen8_enable_rps(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *ring;
- uint32_t rc6_mask = 0, rp_state_cap;
- int unused;
-
- /* 1a: Software RC state - RC0 */
- I915_WRITE(GEN6_RC_STATE, 0);
-
- /* 1c & 1d: Get forcewake during program sequence. Although the driver
- * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
- gen6_gt_force_wake_get(dev_priv);
-
- /* 2a: Disable RC states. */
- I915_WRITE(GEN6_RC_CONTROL, 0);
-
- rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
-
- /* 2b: Program RC6 thresholds.*/
- I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
- I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
- I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
- for_each_ring(ring, dev_priv, unused)
- I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
- I915_WRITE(GEN6_RC_SLEEP, 0);
- I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
-
- /* 3: Enable RC6 */
- if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
- rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
- DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off");
- I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
- GEN6_RC_CTL_EI_MODE(1) |
- rc6_mask);
-
- /* 4 Program defaults and thresholds for RPS*/
- I915_WRITE(GEN6_RPNSWREQ, HSW_FREQUENCY(10)); /* Request 500 MHz */
- I915_WRITE(GEN6_RC_VIDEO_FREQ, HSW_FREQUENCY(12)); /* Request 600 MHz */
- /* NB: Docs say 1s, and 1000000 - which aren't equivalent */
- I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */
-
- /* Docs recommend 900MHz, and 300 MHz respectively */
- I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
- dev_priv->rps.max_delay << 24 |
- dev_priv->rps.min_delay << 16);
-
- I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */
- I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/
- I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */
- I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */
-
- I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
-
- /* 5: Enable RPS */
- I915_WRITE(GEN6_RP_CONTROL,
- GEN6_RP_MEDIA_TURBO |
- GEN6_RP_MEDIA_HW_NORMAL_MODE |
- GEN6_RP_MEDIA_IS_GFX |
- GEN6_RP_ENABLE |
- GEN6_RP_UP_BUSY_AVG |
- GEN6_RP_DOWN_IDLE_AVG);
-
- /* 6: Ring frequency + overclocking (our driver does this later */
-
- gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8);
-
- gen6_enable_rps_interrupts(dev);
-
- gen6_gt_force_wake_put(dev_priv);
-}
-
static void gen6_enable_rps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3869,10 +3501,7 @@ static void gen6_enable_rps(struct drm_device *dev)
/* In units of 50MHz */
dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff;
- dev_priv->rps.min_delay = (rp_state_cap >> 16) & 0xff;
- dev_priv->rps.rp1_delay = (rp_state_cap >> 8) & 0xff;
- dev_priv->rps.rp0_delay = (rp_state_cap >> 0) & 0xff;
- dev_priv->rps.rpe_delay = dev_priv->rps.rp1_delay;
+ dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16;
dev_priv->rps.cur_delay = 0;
/* disable the counters and set deterministic thresholds */
@@ -3889,7 +3518,7 @@ static void gen6_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RC_SLEEP, 0);
I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
- if (IS_IVYBRIDGE(dev))
+ if (INTEL_INFO(dev)->gen <= 6 || IS_IVYBRIDGE(dev))
I915_WRITE(GEN6_RC6_THRESHOLD, 125000);
else
I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
@@ -3910,16 +3539,48 @@ static void gen6_enable_rps(struct drm_device *dev)
rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE;
}
- intel_print_rc6_info(dev, rc6_mask);
+ DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
+ (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
+ (rc6_mask & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
+ (rc6_mask & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off");
I915_WRITE(GEN6_RC_CONTROL,
rc6_mask |
GEN6_RC_CTL_EI_MODE(1) |
GEN6_RC_CTL_HW_ENABLE);
- /* Power down if completely idle for over 50ms */
- I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000);
+ if (IS_HASWELL(dev)) {
+ I915_WRITE(GEN6_RPNSWREQ,
+ HSW_FREQUENCY(10));
+ I915_WRITE(GEN6_RC_VIDEO_FREQ,
+ HSW_FREQUENCY(12));
+ } else {
+ I915_WRITE(GEN6_RPNSWREQ,
+ GEN6_FREQUENCY(10) |
+ GEN6_OFFSET(0) |
+ GEN6_AGGRESSIVE_TURBO);
+ I915_WRITE(GEN6_RC_VIDEO_FREQ,
+ GEN6_FREQUENCY(12));
+ }
+
+ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
+ I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
+ dev_priv->rps.max_delay << 24 |
+ dev_priv->rps.min_delay << 16);
+
+ I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
+ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
+ I915_WRITE(GEN6_RP_UP_EI, 66000);
+ I915_WRITE(GEN6_RP_DOWN_EI, 350000);
+
I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+ I915_WRITE(GEN6_RP_CONTROL,
+ GEN6_RP_MEDIA_TURBO |
+ GEN6_RP_MEDIA_HW_NORMAL_MODE |
+ GEN6_RP_MEDIA_IS_GFX |
+ GEN6_RP_ENABLE |
+ GEN6_RP_UP_BUSY_AVG |
+ (IS_HASWELL(dev) ? GEN7_RP_DOWN_IDLE_AVG : GEN6_RP_DOWN_IDLE_CONT));
ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_MIN_FREQ_TABLE, 0);
if (!ret) {
@@ -3935,8 +3596,7 @@ static void gen6_enable_rps(struct drm_device *dev)
DRM_DEBUG_DRIVER("Failed to set the min frequency\n");
}
- dev_priv->rps.power = HIGH_POWER; /* force a reset */
- gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
+ gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8);
gen6_enable_rps_interrupts(dev);
@@ -3964,28 +3624,23 @@ void gen6_update_ring_freq(struct drm_device *dev)
unsigned int gpu_freq;
unsigned int max_ia_freq, min_ring_freq;
int scaling_factor = 180;
- struct cpufreq_policy *policy;
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
- policy = cpufreq_cpu_get(0);
- if (policy) {
- max_ia_freq = policy->cpuinfo.max_freq;
- cpufreq_cpu_put(policy);
- } else {
- /*
- * Default to measured freq if none found, PCU will ensure we
- * don't go over
- */
+ max_ia_freq = cpufreq_quick_get_max(0);
+ /*
+ * Default to measured freq if none found, PCU will ensure we don't go
+ * over
+ */
+ if (!max_ia_freq)
max_ia_freq = tsc_khz;
- }
/* Convert from kHz to MHz */
max_ia_freq /= 1000;
- min_ring_freq = I915_READ(DCLK) & 0xf;
- /* convert DDR frequency from units of 266.6MHz to bandwidth */
- min_ring_freq = mult_frac(min_ring_freq, 8, 3);
+ min_ring_freq = I915_READ(MCHBAR_MIRROR_BASE_SNB + DCLK);
+ /* convert DDR frequency from units of 133.3MHz to bandwidth */
+ min_ring_freq = (2 * 4 * min_ring_freq + 2) / 3;
/*
* For each potential GPU frequency, load a ring frequency we'd like
@@ -3997,11 +3652,8 @@ void gen6_update_ring_freq(struct drm_device *dev)
int diff = dev_priv->rps.max_delay - gpu_freq;
unsigned int ia_freq = 0, ring_freq = 0;
- if (INTEL_INFO(dev)->gen >= 8) {
- /* max(2 * GT, DDR). NB: GT is 50MHz units */
- ring_freq = max(min_ring_freq, gpu_freq);
- } else if (IS_HASWELL(dev)) {
- ring_freq = mult_frac(gpu_freq, 5, 4);
+ if (IS_HASWELL(dev)) {
+ ring_freq = (gpu_freq * 5 + 3) / 4;
ring_freq = max(min_ring_freq, ring_freq);
/* leave ia_freq as the default, chosen by cpufreq */
} else {
@@ -4057,6 +3709,24 @@ int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
}
+static void vlv_rps_timer_work(struct work_struct *work)
+{
+ drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+ rps.vlv_work.work);
+
+ /*
+ * Timer fired, we must be idle. Drop to min voltage state.
+ * Note: we use RPe here since it should match the
+ * Vmin we were shooting for. That should give us better
+ * perf when we come back out of RC6 than if we used the
+ * min freq available.
+ */
+ mutex_lock(&dev_priv->rps.hw_lock);
+ if (dev_priv->rps.cur_delay > dev_priv->rps.rpe_delay)
+ valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
static void valleyview_setup_pctx(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4103,14 +3773,13 @@ static void valleyview_enable_rps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
- u32 gtfifodbg, val, rc6_mode = 0;
+ u32 gtfifodbg, val;
int i;
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
if ((gtfifodbg = I915_READ(GTFIFODBG))) {
- DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
- gtfifodbg);
+ DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
I915_WRITE(GTFIFODBG, gtfifodbg);
}
@@ -4143,16 +3812,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350);
/* allows RC6 residency counter to work */
- I915_WRITE(VLV_COUNTER_CONTROL,
- _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
- VLV_MEDIA_RC6_COUNT_EN |
- VLV_RENDER_RC6_COUNT_EN));
- if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
- rc6_mode = GEN7_RC_CTL_TO_MODE;
-
- intel_print_rc6_info(dev, rc6_mode);
-
- I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
+ I915_WRITE(0x138104, _MASKED_BIT_ENABLE(0x3));
+ I915_WRITE(GEN6_RC_CONTROL,
+ GEN7_RC_CTL_TO_MODE);
val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
switch ((val >> 6) & 3) {
@@ -4323,8 +3985,6 @@ static void ironlake_enable_rc6(struct drm_device *dev)
I915_WRITE(PWRCTXA, i915_gem_obj_ggtt_offset(dev_priv->ips.pwrctx) | PWRCTX_EN);
I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT);
-
- intel_print_rc6_info(dev, INTEL_RC6_ENABLE);
}
static unsigned long intel_pxfreq(u32 vidfreq)
@@ -4943,12 +4603,13 @@ void intel_disable_gt_powersave(struct drm_device *dev)
} else if (INTEL_INFO(dev)->gen >= 6) {
cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work);
cancel_work_sync(&dev_priv->rps.work);
+ if (IS_VALLEYVIEW(dev))
+ cancel_delayed_work_sync(&dev_priv->rps.vlv_work);
mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev))
valleyview_disable_rps(dev);
else
gen6_disable_rps(dev);
- dev_priv->rps.enabled = false;
mutex_unlock(&dev_priv->rps.hw_lock);
}
}
@@ -4964,14 +4625,10 @@ static void intel_gen6_powersave_work(struct work_struct *work)
if (IS_VALLEYVIEW(dev)) {
valleyview_enable_rps(dev);
- } else if (IS_BROADWELL(dev)) {
- gen8_enable_rps(dev);
- gen6_update_ring_freq(dev);
} else {
gen6_enable_rps(dev);
gen6_update_ring_freq(dev);
}
- dev_priv->rps.enabled = true;
mutex_unlock(&dev_priv->rps.hw_lock);
}
@@ -5015,7 +4672,7 @@ static void g4x_disable_trickle_feed(struct drm_device *dev)
I915_WRITE(DSPCNTR(pipe),
I915_READ(DSPCNTR(pipe)) |
DISPPLANE_TRICKLE_FEED_DISABLE);
- intel_flush_primary_plane(dev_priv, pipe);
+ intel_flush_display_plane(dev_priv, pipe);
}
}
@@ -5275,50 +4932,6 @@ static void lpt_suspend_hw(struct drm_device *dev)
}
}
-static void gen8_init_clock_gating(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe i;
-
- I915_WRITE(WM3_LP_ILK, 0);
- I915_WRITE(WM2_LP_ILK, 0);
- I915_WRITE(WM1_LP_ILK, 0);
-
- /* FIXME(BDW): Check all the w/a, some might only apply to
- * pre-production hw. */
-
- WARN(!i915_preliminary_hw_support,
- "GEN8_CENTROID_PIXEL_OPT_DIS not be needed for production\n");
- I915_WRITE(HALF_SLICE_CHICKEN3,
- _MASKED_BIT_ENABLE(GEN8_CENTROID_PIXEL_OPT_DIS));
- I915_WRITE(HALF_SLICE_CHICKEN3,
- _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS));
- I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_BWGTLB_DISABLE));
-
- I915_WRITE(_3D_CHICKEN3,
- _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(2));
-
- I915_WRITE(COMMON_SLICE_CHICKEN2,
- _MASKED_BIT_ENABLE(GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE));
-
- I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
- _MASKED_BIT_ENABLE(GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE));
-
- /* WaSwitchSolVfFArbitrationPriority */
- I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
-
- /* WaPsrDPAMaskVBlankInSRD */
- I915_WRITE(CHICKEN_PAR1_1,
- I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
-
- /* WaPsrDPRSUnmaskVBlankInSRD */
- for_each_pipe(i) {
- I915_WRITE(CHICKEN_PIPESL_1(i),
- I915_READ(CHICKEN_PIPESL_1(i) |
- DPRS_MASK_VBLANK_SRD));
- }
-}
-
static void haswell_init_clock_gating(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5642,25 +5255,6 @@ void intel_suspend_hw(struct drm_device *dev)
lpt_suspend_hw(dev);
}
-static bool is_always_on_power_domain(struct drm_device *dev,
- enum intel_display_power_domain domain)
-{
- unsigned long always_on_domains;
-
- BUG_ON(BIT(domain) & ~POWER_DOMAIN_MASK);
-
- if (IS_BROADWELL(dev)) {
- always_on_domains = BDW_ALWAYS_ON_POWER_DOMAINS;
- } else if (IS_HASWELL(dev)) {
- always_on_domains = HSW_ALWAYS_ON_POWER_DOMAINS;
- } else {
- WARN_ON(1);
- return true;
- }
-
- return BIT(domain) & always_on_domains;
-}
-
/**
* We should only use the power well if we explicitly asked the hardware to
* enable it, so check if it's enabled and also check if we've requested it to
@@ -5674,11 +5268,23 @@ bool intel_display_power_enabled(struct drm_device *dev,
if (!HAS_POWER_WELL(dev))
return true;
- if (is_always_on_power_domain(dev, domain))
+ switch (domain) {
+ case POWER_DOMAIN_PIPE_A:
+ case POWER_DOMAIN_TRANSCODER_EDP:
return true;
-
- return I915_READ(HSW_PWR_WELL_DRIVER) ==
+ case POWER_DOMAIN_PIPE_B:
+ case POWER_DOMAIN_PIPE_C:
+ case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
+ case POWER_DOMAIN_PIPE_B_PANEL_FITTER:
+ case POWER_DOMAIN_PIPE_C_PANEL_FITTER:
+ case POWER_DOMAIN_TRANSCODER_A:
+ case POWER_DOMAIN_TRANSCODER_B:
+ case POWER_DOMAIN_TRANSCODER_C:
+ return I915_READ(HSW_PWR_WELL_DRIVER) ==
(HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
+ default:
+ BUG();
+ }
}
static void __intel_set_power_well(struct drm_device *dev, bool enable)
@@ -5722,136 +5328,83 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
spin_lock_irqsave(&dev->vbl_lock, irqflags);
for_each_pipe(p)
if (p != PIPE_A)
- dev->vblank[p].last = 0;
+ dev->last_vblank[p] = 0;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
}
}
-static void __intel_power_well_get(struct drm_device *dev,
- struct i915_power_well *power_well)
-{
- if (!power_well->count++)
- __intel_set_power_well(dev, true);
-}
-
-static void __intel_power_well_put(struct drm_device *dev,
- struct i915_power_well *power_well)
-{
- WARN_ON(!power_well->count);
- if (!--power_well->count && i915_disable_power_well)
- __intel_set_power_well(dev, false);
-}
-
-void intel_display_power_get(struct drm_device *dev,
- enum intel_display_power_domain domain)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct i915_power_domains *power_domains;
-
- if (!HAS_POWER_WELL(dev))
- return;
-
- if (is_always_on_power_domain(dev, domain))
- return;
-
- power_domains = &dev_priv->power_domains;
-
- mutex_lock(&power_domains->lock);
- __intel_power_well_get(dev, &power_domains->power_wells[0]);
- mutex_unlock(&power_domains->lock);
-}
-
-void intel_display_power_put(struct drm_device *dev,
- enum intel_display_power_domain domain)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct i915_power_domains *power_domains;
-
- if (!HAS_POWER_WELL(dev))
- return;
-
- if (is_always_on_power_domain(dev, domain))
- return;
-
- power_domains = &dev_priv->power_domains;
-
- mutex_lock(&power_domains->lock);
- __intel_power_well_put(dev, &power_domains->power_wells[0]);
- mutex_unlock(&power_domains->lock);
-}
-
-static struct i915_power_domains *hsw_pwr;
+static struct i915_power_well *hsw_pwr;
/* Display audio driver power well request */
void i915_request_power_well(void)
{
- struct drm_i915_private *dev_priv;
-
if (WARN_ON(!hsw_pwr))
return;
- dev_priv = container_of(hsw_pwr, struct drm_i915_private,
- power_domains);
-
- mutex_lock(&hsw_pwr->lock);
- __intel_power_well_get(dev_priv->dev, &hsw_pwr->power_wells[0]);
- mutex_unlock(&hsw_pwr->lock);
+ spin_lock_irq(&hsw_pwr->lock);
+ if (!hsw_pwr->count++ &&
+ !hsw_pwr->i915_request)
+ __intel_set_power_well(hsw_pwr->device, true);
+ spin_unlock_irq(&hsw_pwr->lock);
}
EXPORT_SYMBOL_GPL(i915_request_power_well);
/* Display audio driver power well release */
void i915_release_power_well(void)
{
- struct drm_i915_private *dev_priv;
-
if (WARN_ON(!hsw_pwr))
return;
- dev_priv = container_of(hsw_pwr, struct drm_i915_private,
- power_domains);
-
- mutex_lock(&hsw_pwr->lock);
- __intel_power_well_put(dev_priv->dev, &hsw_pwr->power_wells[0]);
- mutex_unlock(&hsw_pwr->lock);
+ spin_lock_irq(&hsw_pwr->lock);
+ WARN_ON(!hsw_pwr->count);
+ if (!--hsw_pwr->count &&
+ !hsw_pwr->i915_request)
+ __intel_set_power_well(hsw_pwr->device, false);
+ spin_unlock_irq(&hsw_pwr->lock);
}
EXPORT_SYMBOL_GPL(i915_release_power_well);
-int intel_power_domains_init(struct drm_device *dev)
+int i915_init_power_well(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct i915_power_domains *power_domains = &dev_priv->power_domains;
- struct i915_power_well *power_well;
- mutex_init(&power_domains->lock);
- hsw_pwr = power_domains;
+ hsw_pwr = &dev_priv->power_well;
- power_well = &power_domains->power_wells[0];
- power_well->count = 0;
+ hsw_pwr->device = dev;
+ spin_lock_init(&hsw_pwr->lock);
+ hsw_pwr->count = 0;
return 0;
}
-void intel_power_domains_remove(struct drm_device *dev)
+void i915_remove_power_well(struct drm_device *dev)
{
hsw_pwr = NULL;
}
-static void intel_power_domains_resume(struct drm_device *dev)
+void intel_set_power_well(struct drm_device *dev, bool enable)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct i915_power_domains *power_domains = &dev_priv->power_domains;
- struct i915_power_well *power_well;
+ struct i915_power_well *power_well = &dev_priv->power_well;
if (!HAS_POWER_WELL(dev))
return;
- mutex_lock(&power_domains->lock);
+ if (!i915_disable_power_well && !enable)
+ return;
- power_well = &power_domains->power_wells[0];
- __intel_set_power_well(dev, power_well->count > 0);
+ spin_lock_irq(&power_well->lock);
+ power_well->i915_request = enable;
- mutex_unlock(&power_domains->lock);
+ /* only reject "disable" power well request */
+ if (power_well->count && !enable) {
+ spin_unlock_irq(&power_well->lock);
+ return;
+ }
+
+ __intel_set_power_well(dev, enable);
+ spin_unlock_irq(&power_well->lock);
}
/*
@@ -5860,7 +5413,7 @@ static void intel_power_domains_resume(struct drm_device *dev)
* to be enabled, and it will only be disabled if none of the registers is
* requesting it to be enabled.
*/
-void intel_power_domains_init_hw(struct drm_device *dev)
+void intel_init_power_well(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5868,8 +5421,7 @@ void intel_power_domains_init_hw(struct drm_device *dev)
return;
/* For now, we need the power well to be always enabled. */
- intel_display_set_init_power(dev, true);
- intel_power_domains_resume(dev);
+ intel_set_power_well(dev, true);
/* We're taking over the BIOS, so clear any requests made by it since
* the driver is in charge now. */
@@ -5973,8 +5525,6 @@ void intel_init_pm(struct drm_device *dev)
dev_priv->display.update_wm = NULL;
}
dev_priv->display.init_clock_gating = haswell_init_clock_gating;
- } else if (INTEL_INFO(dev)->gen == 8) {
- dev_priv->display.init_clock_gating = gen8_init_clock_gating;
} else
dev_priv->display.update_wm = NULL;
} else if (IS_VALLEYVIEW(dev)) {
@@ -6136,4 +5686,7 @@ void intel_pm_init(struct drm_device *dev)
INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
intel_gen6_powersave_work);
+
+ INIT_DELAYED_WORK(&dev_priv->rps.vlv_work, vlv_rps_timer_work);
}
+
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b620337..460ee10 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -41,16 +41,6 @@ static inline int ring_space(struct intel_ring_buffer *ring)
return space;
}
-void __intel_ring_advance(struct intel_ring_buffer *ring)
-{
- struct drm_i915_private *dev_priv = ring->dev->dev_private;
-
- ring->tail &= ring->size - 1;
- if (dev_priv->gpu_error.stop_rings & intel_ring_flag(ring))
- return;
- ring->write_tail(ring, ring->tail);
-}
-
static int
gen2_render_ring_flush(struct intel_ring_buffer *ring,
u32 invalidate_domains,
@@ -360,47 +350,6 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring,
return 0;
}
-static int
-gen8_render_ring_flush(struct intel_ring_buffer *ring,
- u32 invalidate_domains, u32 flush_domains)
-{
- u32 flags = 0;
- u32 scratch_addr = ring->scratch.gtt_offset + 128;
- int ret;
-
- flags |= PIPE_CONTROL_CS_STALL;
-
- if (flush_domains) {
- flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
- flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
- }
- if (invalidate_domains) {
- flags |= PIPE_CONTROL_TLB_INVALIDATE;
- flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
- flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
- flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
- flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
- flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
- flags |= PIPE_CONTROL_QW_WRITE;
- flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
- }
-
- ret = intel_ring_begin(ring, 6);
- if (ret)
- return ret;
-
- intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
- intel_ring_emit(ring, flags);
- intel_ring_emit(ring, scratch_addr);
- intel_ring_emit(ring, 0);
- intel_ring_emit(ring, 0);
- intel_ring_emit(ring, 0);
- intel_ring_advance(ring);
-
- return 0;
-
-}
-
static void ring_write_tail(struct intel_ring_buffer *ring,
u32 value)
{
@@ -436,7 +385,8 @@ static int init_ring_common(struct intel_ring_buffer *ring)
int ret = 0;
u32 head;
- gen6_gt_force_wake_get(dev_priv);
+ if (HAS_FORCE_WAKE(dev))
+ gen6_gt_force_wake_get(dev_priv);
if (I915_NEED_GFX_HWS(dev))
intel_ring_setup_status_page(ring);
@@ -509,7 +459,8 @@ static int init_ring_common(struct intel_ring_buffer *ring)
memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
out:
- gen6_gt_force_wake_put(dev_priv);
+ if (HAS_FORCE_WAKE(dev))
+ gen6_gt_force_wake_put(dev_priv);
return ret;
}
@@ -608,8 +559,8 @@ static int init_render_ring(struct intel_ring_buffer *ring)
if (INTEL_INFO(dev)->gen >= 6)
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
- if (HAS_L3_DPF(dev))
- I915_WRITE_IMR(ring, ~GT_PARITY_ERROR(dev));
+ if (HAS_L3_GPU_CACHE(dev))
+ I915_WRITE_IMR(ring, ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
return ret;
}
@@ -642,7 +593,7 @@ update_mboxes(struct intel_ring_buffer *ring,
#define MBOX_UPDATE_DWORDS 4
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(ring, mmio_offset);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring, ring->outstanding_lazy_request);
intel_ring_emit(ring, MI_NOOP);
}
@@ -678,9 +629,9 @@ gen6_add_request(struct intel_ring_buffer *ring)
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring, ring->outstanding_lazy_request);
intel_ring_emit(ring, MI_USER_INTERRUPT);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
}
@@ -772,7 +723,7 @@ pc_render_add_request(struct intel_ring_buffer *ring)
PIPE_CONTROL_WRITE_FLUSH |
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring, ring->outstanding_lazy_request);
intel_ring_emit(ring, 0);
PIPE_CONTROL_FLUSH(ring, scratch_addr);
scratch_addr += 128; /* write to separate cachelines */
@@ -791,9 +742,9 @@ pc_render_add_request(struct intel_ring_buffer *ring)
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
PIPE_CONTROL_NOTIFY);
intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring, ring->outstanding_lazy_request);
intel_ring_emit(ring, 0);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
}
@@ -1012,9 +963,9 @@ i9xx_add_request(struct intel_ring_buffer *ring)
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring, ring->outstanding_lazy_request);
intel_ring_emit(ring, MI_USER_INTERRUPT);
- __intel_ring_advance(ring);
+ intel_ring_advance(ring);
return 0;
}
@@ -1036,10 +987,10 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (ring->irq_refcount++ == 0) {
- if (HAS_L3_DPF(dev) && ring->id == RCS)
+ if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
I915_WRITE_IMR(ring,
~(ring->irq_enable_mask |
- GT_PARITY_ERROR(dev)));
+ GT_RENDER_L3_PARITY_ERROR_INTERRUPT));
else
I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
ilk_enable_gt_irq(dev_priv, ring->irq_enable_mask);
@@ -1058,8 +1009,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (--ring->irq_refcount == 0) {
- if (HAS_L3_DPF(dev) && ring->id == RCS)
- I915_WRITE_IMR(ring, ~GT_PARITY_ERROR(dev));
+ if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
+ I915_WRITE_IMR(ring,
+ ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
else
I915_WRITE_IMR(ring, ~0);
ilk_disable_gt_irq(dev_priv, ring->irq_enable_mask);
@@ -1107,52 +1059,6 @@ hsw_vebox_put_irq(struct intel_ring_buffer *ring)
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
}
-static bool
-gen8_ring_get_irq(struct intel_ring_buffer *ring)
-{
- struct drm_device *dev = ring->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- if (!dev->irq_enabled)
- return false;
-
- spin_lock_irqsave(&dev_priv->irq_lock, flags);
- if (ring->irq_refcount++ == 0) {
- if (HAS_L3_DPF(dev) && ring->id == RCS) {
- I915_WRITE_IMR(ring,
- ~(ring->irq_enable_mask |
- GT_RENDER_L3_PARITY_ERROR_INTERRUPT));
- } else {
- I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
- }
- POSTING_READ(RING_IMR(ring->mmio_base));
- }
- spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
-
- return true;
-}
-
-static void
-gen8_ring_put_irq(struct intel_ring_buffer *ring)
-{
- struct drm_device *dev = ring->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->irq_lock, flags);
- if (--ring->irq_refcount == 0) {
- if (HAS_L3_DPF(dev) && ring->id == RCS) {
- I915_WRITE_IMR(ring,
- ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
- } else {
- I915_WRITE_IMR(ring, ~0);
- }
- POSTING_READ(RING_IMR(ring->mmio_base));
- }
- spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
-}
-
static int
i965_dispatch_execbuffer(struct intel_ring_buffer *ring,
u32 offset, u32 length,
@@ -1411,7 +1317,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring)
/* Disable the ring buffer. The ring must be idle at this point */
dev_priv = ring->dev->dev_private;
ret = intel_ring_idle(ring);
- if (ret && !i915_reset_in_progress(&dev_priv->gpu_error))
+ if (ret)
DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n",
ring->name, ret);
@@ -1422,8 +1328,6 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring)
i915_gem_object_unpin(ring->obj);
drm_gem_object_unreference(&ring->obj->base);
ring->obj = NULL;
- ring->preallocated_lazy_request = NULL;
- ring->outstanding_lazy_seqno = 0;
if (ring->cleanup)
ring->cleanup(ring);
@@ -1510,9 +1414,6 @@ static int ring_wait_for_space(struct intel_ring_buffer *ring, int n)
if (ret != -ENOSPC)
return ret;
- /* force the tail write in case we have been skipping them */
- __intel_ring_advance(ring);
-
trace_i915_ring_wait_begin(ring);
/* With GEM the hangcheck timer should kick us out of the loop,
* leaving it early runs the risk of corrupting GEM state (due
@@ -1574,7 +1475,7 @@ int intel_ring_idle(struct intel_ring_buffer *ring)
int ret;
/* We need to add any requests required to flush the objects and ring */
- if (ring->outstanding_lazy_seqno) {
+ if (ring->outstanding_lazy_request) {
ret = i915_add_request(ring, NULL);
if (ret)
return ret;
@@ -1594,20 +1495,10 @@ int intel_ring_idle(struct intel_ring_buffer *ring)
static int
intel_ring_alloc_seqno(struct intel_ring_buffer *ring)
{
- if (ring->outstanding_lazy_seqno)
+ if (ring->outstanding_lazy_request)
return 0;
- if (ring->preallocated_lazy_request == NULL) {
- struct drm_i915_gem_request *request;
-
- request = kmalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
- ring->preallocated_lazy_request = request;
- }
-
- return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+ return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request);
}
static int __intel_ring_begin(struct intel_ring_buffer *ring,
@@ -1654,7 +1545,7 @@ void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
- BUG_ON(ring->outstanding_lazy_seqno);
+ BUG_ON(ring->outstanding_lazy_request);
if (INTEL_INFO(ring->dev)->gen >= 6) {
I915_WRITE(RING_SYNC_0(ring->mmio_base), 0);
@@ -1667,6 +1558,17 @@ void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
ring->hangcheck.seqno = seqno;
}
+void intel_ring_advance(struct intel_ring_buffer *ring)
+{
+ struct drm_i915_private *dev_priv = ring->dev->dev_private;
+
+ ring->tail &= ring->size - 1;
+ if (dev_priv->gpu_error.stop_rings & intel_ring_flag(ring))
+ return;
+ ring->write_tail(ring, ring->tail);
+}
+
+
static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring,
u32 value)
{
@@ -1711,8 +1613,6 @@ static int gen6_bsd_ring_flush(struct intel_ring_buffer *ring,
return ret;
cmd = MI_FLUSH_DW;
- if (INTEL_INFO(ring->dev)->gen >= 8)
- cmd += 1;
/*
* Bspec vol 1c.5 - video engine command streamer:
* "If ENABLED, all TLBs will be invalidated once the flush
@@ -1724,38 +1624,9 @@ static int gen6_bsd_ring_flush(struct intel_ring_buffer *ring,
MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
intel_ring_emit(ring, cmd);
intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
- if (INTEL_INFO(ring->dev)->gen >= 8) {
- intel_ring_emit(ring, 0); /* upper addr */
- intel_ring_emit(ring, 0); /* value */
- } else {
- intel_ring_emit(ring, 0);
- intel_ring_emit(ring, MI_NOOP);
- }
- intel_ring_advance(ring);
- return 0;
-}
-
-static int
-gen8_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
- u32 offset, u32 len,
- unsigned flags)
-{
- struct drm_i915_private *dev_priv = ring->dev->dev_private;
- bool ppgtt = dev_priv->mm.aliasing_ppgtt != NULL &&
- !(flags & I915_DISPATCH_SECURE);
- int ret;
-
- ret = intel_ring_begin(ring, 4);
- if (ret)
- return ret;
-
- /* FIXME(BDW): Address space and security selectors. */
- intel_ring_emit(ring, MI_BATCH_BUFFER_START_GEN8 | (ppgtt<<8));
- intel_ring_emit(ring, offset);
intel_ring_emit(ring, 0);
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
-
return 0;
}
@@ -1815,8 +1686,6 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring,
return ret;
cmd = MI_FLUSH_DW;
- if (INTEL_INFO(ring->dev)->gen >= 8)
- cmd += 1;
/*
* Bspec vol 1c.3 - blitter engine command streamer:
* "If ENABLED, all TLBs will be invalidated once the flush
@@ -1828,13 +1697,8 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring,
MI_FLUSH_DW_OP_STOREDW;
intel_ring_emit(ring, cmd);
intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
- if (INTEL_INFO(ring->dev)->gen >= 8) {
- intel_ring_emit(ring, 0); /* upper addr */
- intel_ring_emit(ring, 0); /* value */
- } else {
- intel_ring_emit(ring, 0);
- intel_ring_emit(ring, MI_NOOP);
- }
+ intel_ring_emit(ring, 0);
+ intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
if (IS_GEN7(dev) && flush)
@@ -1857,14 +1721,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->flush = gen7_render_ring_flush;
if (INTEL_INFO(dev)->gen == 6)
ring->flush = gen6_render_ring_flush;
- if (INTEL_INFO(dev)->gen >= 8) {
- ring->flush = gen8_render_ring_flush;
- ring->irq_get = gen8_ring_get_irq;
- ring->irq_put = gen8_ring_put_irq;
- } else {
- ring->irq_get = gen6_ring_get_irq;
- ring->irq_put = gen6_ring_put_irq;
- }
+ ring->irq_get = gen6_ring_get_irq;
+ ring->irq_put = gen6_ring_put_irq;
ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
@@ -1906,8 +1764,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->write_tail = ring_write_tail;
if (IS_HASWELL(dev))
ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
- else if (IS_GEN8(dev))
- ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
else if (INTEL_INFO(dev)->gen >= 6)
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
else if (INTEL_INFO(dev)->gen >= 4)
@@ -2021,7 +1877,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
ring->id = VCS;
ring->write_tail = ring_write_tail;
- if (INTEL_INFO(dev)->gen >= 6) {
+ if (IS_GEN6(dev) || IS_GEN7(dev)) {
ring->mmio_base = GEN6_BSD_RING_BASE;
/* gen6 bsd needs a special wa for tail updates */
if (IS_GEN6(dev))
@@ -2030,20 +1886,10 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
ring->add_request = gen6_add_request;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
- if (INTEL_INFO(dev)->gen >= 8) {
- ring->irq_enable_mask =
- GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT;
- ring->irq_get = gen8_ring_get_irq;
- ring->irq_put = gen8_ring_put_irq;
- ring->dispatch_execbuffer =
- gen8_ring_dispatch_execbuffer;
- } else {
- ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
- ring->irq_get = gen6_ring_get_irq;
- ring->irq_put = gen6_ring_put_irq;
- ring->dispatch_execbuffer =
- gen6_ring_dispatch_execbuffer;
- }
+ ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
+ ring->irq_get = gen6_ring_get_irq;
+ ring->irq_put = gen6_ring_put_irq;
+ ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
ring->sync_to = gen6_ring_sync;
ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR;
ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID;
@@ -2089,18 +1935,10 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->add_request = gen6_add_request;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
- if (INTEL_INFO(dev)->gen >= 8) {
- ring->irq_enable_mask =
- GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT;
- ring->irq_get = gen8_ring_get_irq;
- ring->irq_put = gen8_ring_put_irq;
- ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
- } else {
- ring->irq_enable_mask = GT_BLT_USER_INTERRUPT;
- ring->irq_get = gen6_ring_get_irq;
- ring->irq_put = gen6_ring_put_irq;
- ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
- }
+ ring->irq_enable_mask = GT_BLT_USER_INTERRUPT;
+ ring->irq_get = gen6_ring_get_irq;
+ ring->irq_put = gen6_ring_put_irq;
+ ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
ring->sync_to = gen6_ring_sync;
ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR;
ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV;
@@ -2129,19 +1967,10 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->add_request = gen6_add_request;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
-
- if (INTEL_INFO(dev)->gen >= 8) {
- ring->irq_enable_mask =
- GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT;
- ring->irq_get = gen8_ring_get_irq;
- ring->irq_put = gen8_ring_put_irq;
- ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
- } else {
- ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
- ring->irq_get = hsw_vebox_get_irq;
- ring->irq_put = hsw_vebox_put_irq;
- ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
- }
+ ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
+ ring->irq_get = hsw_vebox_get_irq;
+ ring->irq_put = hsw_vebox_put_irq;
+ ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
ring->sync_to = gen6_ring_sync;
ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VER;
ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_VEV;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 71a73f4..68b1ca974 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -34,7 +34,6 @@ struct intel_hw_status_page {
#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val)
enum intel_ring_hangcheck_action {
- HANGCHECK_IDLE = 0,
HANGCHECK_WAIT,
HANGCHECK_ACTIVE,
HANGCHECK_KICK,
@@ -141,8 +140,7 @@ struct intel_ring_buffer {
/**
* Do we have some not yet emitted requests outstanding?
*/
- struct drm_i915_gem_request *preallocated_lazy_request;
- u32 outstanding_lazy_seqno;
+ u32 outstanding_lazy_request;
bool gpu_caches_dirty;
bool fbc_dirty;
@@ -239,12 +237,7 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring,
iowrite32(data, ring->virtual_start + ring->tail);
ring->tail += 4;
}
-static inline void intel_ring_advance(struct intel_ring_buffer *ring)
-{
- ring->tail &= ring->size - 1;
-}
-void __intel_ring_advance(struct intel_ring_buffer *ring);
-
+void intel_ring_advance(struct intel_ring_buffer *ring);
int __must_check intel_ring_idle(struct intel_ring_buffer *ring);
void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno);
int intel_ring_flush_all_caches(struct intel_ring_buffer *ring);
@@ -265,8 +258,8 @@ static inline u32 intel_ring_get_tail(struct intel_ring_buffer *ring)
static inline u32 intel_ring_get_seqno(struct intel_ring_buffer *ring)
{
- BUG_ON(ring->outstanding_lazy_seqno == 0);
- return ring->outstanding_lazy_seqno;
+ BUG_ON(ring->outstanding_lazy_request == 0);
+ return ring->outstanding_lazy_request;
}
static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index a583e8f..49482fd 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -539,7 +539,7 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
goto log_fail;
while ((status == SDVO_CMD_STATUS_PENDING ||
- status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) {
+ status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) {
if (retry < 10)
msleep(15);
else
@@ -1068,7 +1068,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config)
{
- unsigned dotclock = pipe_config->port_clock;
+ unsigned dotclock = pipe_config->adjusted_mode.clock;
struct dpll *clock = &pipe_config->dpll;
/* SDVO TV has fixed PLL values depend on its clock range,
@@ -1133,6 +1133,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
*/
pipe_config->pixel_multiplier =
intel_sdvo_get_pixel_multiplier(adjusted_mode);
+ adjusted_mode->clock *= pipe_config->pixel_multiplier;
if (intel_sdvo->color_range_auto) {
/* See CEA-861-E - 5.1 Default Encoding Parameters */
@@ -1216,7 +1217,11 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder)
!intel_sdvo_set_tv_format(intel_sdvo))
return;
+ /* We have tried to get input timing in mode_fixup, and filled into
+ * adjusted_mode.
+ */
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+ input_dtd.part1.clock /= crtc->config.pixel_multiplier;
if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
@@ -1325,7 +1330,6 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
struct intel_sdvo_dtd dtd;
int encoder_pixel_multiplier = 0;
- int dotclock;
u32 flags = 0, sdvox;
u8 val;
bool ret;
@@ -1364,13 +1368,6 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>> SDVO_PORT_MULTIPLY_SHIFT) + 1;
}
- dotclock = pipe_config->port_clock / pipe_config->pixel_multiplier;
-
- if (HAS_PCH_SPLIT(dev))
- ironlake_check_encoder_dotclock(pipe_config, dotclock);
-
- pipe_config->adjusted_mode.crtc_clock = dotclock;
-
/* Cross check the port pixel multiplier with the sdvo encoder state. */
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
&val, 1)) {
@@ -1773,9 +1770,6 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
{
struct edid *edid;
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
- connector->base.id, drm_get_connector_name(connector));
-
/* set the bus switch and get the modes */
edid = intel_sdvo_get_edid(connector);
@@ -1871,9 +1865,6 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
uint32_t reply = 0, format_map = 0;
int i;
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
- connector->base.id, drm_get_connector_name(connector));
-
/* Read the list of supported input resolutions for the selected TV
* format.
*/
@@ -1908,9 +1899,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
struct drm_i915_private *dev_priv = connector->dev->dev_private;
struct drm_display_mode *newmode;
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
- connector->base.id, drm_get_connector_name(connector));
-
/*
* Fetch modes from VBT. For SDVO prefer the VBT mode since some
* SDVO->LVDS transcoders can't cope with the EDID mode.
@@ -1942,6 +1930,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
break;
}
}
+
}
static int intel_sdvo_get_modes(struct drm_connector *connector)
@@ -2009,6 +1998,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
intel_sdvo_connector->tv_format);
intel_sdvo_destroy_enhance_property(connector);
+ drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(intel_sdvo_connector);
}
@@ -2404,9 +2394,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
struct intel_connector *intel_connector;
struct intel_sdvo_connector *intel_sdvo_connector;
- DRM_DEBUG_KMS("initialising DVI device %d\n", device);
-
- intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
+ intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
if (!intel_sdvo_connector)
return false;
@@ -2454,9 +2442,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
struct intel_connector *intel_connector;
struct intel_sdvo_connector *intel_sdvo_connector;
- DRM_DEBUG_KMS("initialising TV type %d\n", type);
-
- intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
+ intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
if (!intel_sdvo_connector)
return false;
@@ -2481,7 +2467,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
return true;
err:
- drm_sysfs_connector_remove(connector);
intel_sdvo_destroy(connector);
return false;
}
@@ -2494,9 +2479,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
struct intel_connector *intel_connector;
struct intel_sdvo_connector *intel_sdvo_connector;
- DRM_DEBUG_KMS("initialising analog device %d\n", device);
-
- intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
+ intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
if (!intel_sdvo_connector)
return false;
@@ -2527,9 +2510,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
struct intel_connector *intel_connector;
struct intel_sdvo_connector *intel_sdvo_connector;
- DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
-
- intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL);
+ intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
if (!intel_sdvo_connector)
return false;
@@ -2553,7 +2534,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
return true;
err:
- drm_sysfs_connector_remove(connector);
intel_sdvo_destroy(connector);
return false;
}
@@ -2625,10 +2605,8 @@ static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
list_for_each_entry_safe(connector, tmp,
&dev->mode_config.connector_list, head) {
- if (intel_attached_encoder(connector) == &intel_sdvo->base) {
- drm_sysfs_connector_remove(connector);
+ if (intel_attached_encoder(connector) == &intel_sdvo->base)
intel_sdvo_destroy(connector);
- }
}
}
@@ -2898,7 +2876,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
struct intel_encoder *intel_encoder;
struct intel_sdvo *intel_sdvo;
int i;
- intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL);
+ intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
if (!intel_sdvo)
return false;
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 9944d81..9a0e6c5 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -25,10 +25,7 @@
#include "i915_drv.h"
#include "intel_drv.h"
-/*
- * IOSF sideband, see VLV2_SidebandMsg_HAS.docx and
- * VLV_VLV2_PUNIT_HAS_0.8.docx
- */
+/* IOSF sideband */
static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
u32 port, u32 opcode, u32 addr, u32 *val)
{
@@ -104,83 +101,19 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
return val;
}
-u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg)
-{
- u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
- PUNIT_OPCODE_REG_READ, reg, &val);
- return val;
-}
-
-void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
-{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
- PUNIT_OPCODE_REG_WRITE, reg, &val);
-}
-
-u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg)
-{
- u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
- PUNIT_OPCODE_REG_READ, reg, &val);
- return val;
-}
-
-void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
-{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
- PUNIT_OPCODE_REG_WRITE, reg, &val);
-}
-
-u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
-{
- u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
- PUNIT_OPCODE_REG_READ, reg, &val);
- return val;
-}
-
-void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
-{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
- PUNIT_OPCODE_REG_WRITE, reg, &val);
-}
-
-u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg)
-{
- u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
- PUNIT_OPCODE_REG_READ, reg, &val);
- return val;
-}
-
-void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
-{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
- PUNIT_OPCODE_REG_WRITE, reg, &val);
-}
-
-static u32 vlv_get_phy_port(enum pipe pipe)
-{
- u32 port = IOSF_PORT_DPIO;
-
- WARN_ON ((pipe != PIPE_A) && (pipe != PIPE_B));
-
- return port;
-}
-
-u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg)
+u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg)
{
u32 val = 0;
- vlv_sideband_rw(dev_priv, DPIO_DEVFN, vlv_get_phy_port(pipe),
+ vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
DPIO_OPCODE_REG_READ, reg, &val);
+
return val;
}
-void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val)
+void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val)
{
- vlv_sideband_rw(dev_priv, DPIO_DEVFN, vlv_get_phy_port(pipe),
+ vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
DPIO_OPCODE_REG_WRITE, reg, &val);
}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b9fabf8..ad6ec4b 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -260,14 +260,14 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (obj->tiling_mode != I915_TILING_NONE)
sprctl |= SPRITE_TILED;
- if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+ if (IS_HASWELL(dev))
sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
else
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
sprctl |= SPRITE_ENABLE;
- if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+ if (IS_HASWELL(dev))
sprctl |= SPRITE_PIPE_CSC_ENABLE;
intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true,
@@ -288,7 +288,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
dev_priv->sprite_scaling_enabled |= 1 << pipe;
if (!scaling_was_enabled) {
- intel_update_watermarks(crtc);
+ intel_update_watermarks(dev);
intel_wait_for_vblank(dev, pipe);
}
sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
@@ -306,7 +306,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
* register */
- if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+ if (IS_HASWELL(dev))
I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
else if (obj->tiling_mode != I915_TILING_NONE)
I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
@@ -323,7 +323,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
/* potentially re-enable LP watermarks */
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
- intel_update_watermarks(crtc);
+ intel_update_watermarks(dev);
}
static void
@@ -349,7 +349,7 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
/* potentially re-enable LP watermarks */
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
- intel_update_watermarks(crtc);
+ intel_update_watermarks(dev);
}
static int
@@ -521,28 +521,13 @@ intel_enable_primary(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int reg = DSPCNTR(intel_crtc->plane);
- if (intel_crtc->primary_enabled)
+ if (!intel_crtc->primary_disabled)
return;
- intel_crtc->primary_enabled = true;
+ intel_crtc->primary_disabled = false;
+ intel_update_fbc(dev);
I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
- intel_flush_primary_plane(dev_priv, intel_crtc->plane);
-
- /*
- * FIXME IPS should be fine as long as one plane is
- * enabled, but in practice it seems to have problems
- * when going from primary only to sprite only and vice
- * versa.
- */
- if (intel_crtc->config.ips_enabled) {
- intel_wait_for_vblank(dev, intel_crtc->pipe);
- hsw_enable_ips(intel_crtc);
- }
-
- mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
- mutex_unlock(&dev->struct_mutex);
}
static void
@@ -553,26 +538,13 @@ intel_disable_primary(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int reg = DSPCNTR(intel_crtc->plane);
- if (!intel_crtc->primary_enabled)
+ if (intel_crtc->primary_disabled)
return;
- intel_crtc->primary_enabled = false;
-
- mutex_lock(&dev->struct_mutex);
- if (dev_priv->fbc.plane == intel_crtc->plane)
- intel_disable_fbc(dev);
- mutex_unlock(&dev->struct_mutex);
-
- /*
- * FIXME IPS should be fine as long as one plane is
- * enabled, but in practice it seems to have problems
- * when going from primary only to sprite only and vice
- * versa.
- */
- hsw_disable_ips(intel_crtc);
-
I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
- intel_flush_primary_plane(dev_priv, intel_crtc->plane);
+
+ intel_crtc->primary_disabled = true;
+ intel_update_fbc(dev);
}
static int
@@ -651,12 +623,15 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
uint32_t src_w, uint32_t src_h)
{
struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane = to_intel_plane(plane);
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
- struct drm_i915_gem_object *old_obj = intel_plane->obj;
- int ret;
+ struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj, *old_obj;
+ int pipe = intel_plane->pipe;
+ enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
+ pipe);
+ int ret = 0;
bool disable_primary = false;
bool visible;
int hscale, vscale;
@@ -677,24 +652,30 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
.y2 = crtc_y + crtc_h,
};
const struct drm_rect clip = {
- .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
- .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
- };
- const struct {
- int crtc_x, crtc_y;
- unsigned int crtc_w, crtc_h;
- uint32_t src_x, src_y, src_w, src_h;
- } orig = {
- .crtc_x = crtc_x,
- .crtc_y = crtc_y,
- .crtc_w = crtc_w,
- .crtc_h = crtc_h,
- .src_x = src_x,
- .src_y = src_y,
- .src_w = src_w,
- .src_h = src_h,
+ .x2 = crtc->mode.hdisplay,
+ .y2 = crtc->mode.vdisplay,
};
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ old_obj = intel_plane->obj;
+
+ intel_plane->crtc_x = crtc_x;
+ intel_plane->crtc_y = crtc_y;
+ intel_plane->crtc_w = crtc_w;
+ intel_plane->crtc_h = crtc_h;
+ intel_plane->src_x = src_x;
+ intel_plane->src_y = src_y;
+ intel_plane->src_w = src_w;
+ intel_plane->src_h = src_h;
+
+ /* Pipe must be running... */
+ if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) {
+ DRM_DEBUG_KMS("Pipe disabled\n");
+ return -EINVAL;
+ }
+
/* Don't modify another pipe's plane */
if (intel_plane->pipe != intel_crtc->pipe) {
DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
@@ -829,7 +810,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
* we can disable the primary and save power.
*/
disable_primary = drm_rect_equals(&dst, &clip);
- WARN_ON(disable_primary && !visible && intel_crtc->active);
+ WARN_ON(disable_primary && !visible);
mutex_lock(&dev->struct_mutex);
@@ -839,40 +820,27 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
* the sprite planes only require 128KiB alignment and 32 PTE padding.
*/
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
-
- mutex_unlock(&dev->struct_mutex);
-
if (ret)
- return ret;
-
- intel_plane->crtc_x = orig.crtc_x;
- intel_plane->crtc_y = orig.crtc_y;
- intel_plane->crtc_w = orig.crtc_w;
- intel_plane->crtc_h = orig.crtc_h;
- intel_plane->src_x = orig.src_x;
- intel_plane->src_y = orig.src_y;
- intel_plane->src_w = orig.src_w;
- intel_plane->src_h = orig.src_h;
+ goto out_unlock;
+
intel_plane->obj = obj;
- if (intel_crtc->active) {
- /*
- * Be sure to re-enable the primary before the sprite is no longer
- * covering it fully.
- */
- if (!disable_primary)
- intel_enable_primary(crtc);
-
- if (visible)
- intel_plane->update_plane(plane, crtc, fb, obj,
- crtc_x, crtc_y, crtc_w, crtc_h,
- src_x, src_y, src_w, src_h);
- else
- intel_plane->disable_plane(plane, crtc);
-
- if (disable_primary)
- intel_disable_primary(crtc);
- }
+ /*
+ * Be sure to re-enable the primary before the sprite is no longer
+ * covering it fully.
+ */
+ if (!disable_primary)
+ intel_enable_primary(crtc);
+
+ if (visible)
+ intel_plane->update_plane(plane, crtc, fb, obj,
+ crtc_x, crtc_y, crtc_w, crtc_h,
+ src_x, src_y, src_w, src_h);
+ else
+ intel_plane->disable_plane(plane, crtc);
+
+ if (disable_primary)
+ intel_disable_primary(crtc);
/* Unpin old obj after new one is active to avoid ugliness */
if (old_obj) {
@@ -882,15 +850,17 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
* wait for vblank to avoid ugliness, we only need to
* do the pin & ref bookkeeping.
*/
- if (old_obj != obj && intel_crtc->active)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
-
- mutex_lock(&dev->struct_mutex);
+ if (old_obj != obj) {
+ mutex_unlock(&dev->struct_mutex);
+ intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
+ mutex_lock(&dev->struct_mutex);
+ }
intel_unpin_fb_obj(old_obj);
- mutex_unlock(&dev->struct_mutex);
}
- return 0;
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
static int
@@ -898,7 +868,7 @@ intel_disable_plane(struct drm_plane *plane)
{
struct drm_device *dev = plane->dev;
struct intel_plane *intel_plane = to_intel_plane(plane);
- struct intel_crtc *intel_crtc;
+ int ret = 0;
if (!plane->fb)
return 0;
@@ -906,25 +876,21 @@ intel_disable_plane(struct drm_plane *plane)
if (WARN_ON(!plane->crtc))
return -EINVAL;
- intel_crtc = to_intel_crtc(plane->crtc);
+ intel_enable_primary(plane->crtc);
+ intel_plane->disable_plane(plane, plane->crtc);
- if (intel_crtc->active) {
- intel_enable_primary(plane->crtc);
- intel_plane->disable_plane(plane, plane->crtc);
- }
-
- if (intel_plane->obj) {
- if (intel_crtc->active)
- intel_wait_for_vblank(dev, intel_plane->pipe);
+ if (!intel_plane->obj)
+ goto out;
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(intel_plane->obj);
- mutex_unlock(&dev->struct_mutex);
+ intel_wait_for_vblank(dev, intel_plane->pipe);
- intel_plane->obj = NULL;
- }
+ mutex_lock(&dev->struct_mutex);
+ intel_unpin_fb_obj(intel_plane->obj);
+ intel_plane->obj = NULL;
+ mutex_unlock(&dev->struct_mutex);
+out:
- return 0;
+ return ret;
}
static void intel_destroy_plane(struct drm_plane *plane)
@@ -955,7 +921,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out_unlock;
}
@@ -984,7 +950,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out_unlock;
}
@@ -1068,7 +1034,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
if (INTEL_INFO(dev)->gen < 5)
return -ENODEV;
- intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
if (!intel_plane)
return -ENOMEM;
@@ -1092,7 +1058,6 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
break;
case 7:
- case 8:
if (IS_IVYBRIDGE(dev)) {
intel_plane->can_scale = true;
intel_plane->max_downscale = 2;
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 22cf0f4..dd6f84b 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -902,13 +902,6 @@ intel_tv_mode_valid(struct drm_connector *connector,
}
-static void
-intel_tv_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
-{
- pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
-}
-
static bool
intel_tv_compute_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
@@ -919,7 +912,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
if (!tv_mode)
return false;
- pipe_config->adjusted_mode.crtc_clock = tv_mode->clock;
+ pipe_config->adjusted_mode.clock = tv_mode->clock;
DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
pipe_config->pipe_bpp = 8*3;
@@ -1051,7 +1044,7 @@ static void intel_tv_mode_set(struct intel_encoder *encoder)
tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
/* Enable two fixes for the chips that need them. */
- if (dev->pdev->device < 0x2772)
+ if (dev->pci_device < 0x2772)
tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
I915_WRITE(TV_H_CTL_1, hctl1);
@@ -1101,7 +1094,7 @@ static void intel_tv_mode_set(struct intel_encoder *encoder)
unsigned int xsize, ysize;
/* Pipe must be off here */
I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
- intel_flush_primary_plane(dev_priv, intel_crtc->plane);
+ intel_flush_display_plane(dev_priv, intel_crtc->plane);
/* Wait for vblank for the disable to take effect */
if (IS_GEN2(dev))
@@ -1130,7 +1123,7 @@ static void intel_tv_mode_set(struct intel_encoder *encoder)
I915_WRITE(pipeconf_reg, pipeconf);
I915_WRITE(dspcntr_reg, dspcntr);
- intel_flush_primary_plane(dev_priv, intel_crtc->plane);
+ intel_flush_display_plane(dev_priv, intel_crtc->plane);
}
j = 0;
@@ -1440,6 +1433,7 @@ intel_tv_get_modes(struct drm_connector *connector)
static void
intel_tv_destroy(struct drm_connector *connector)
{
+ drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -1524,7 +1518,7 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs = {
static int tv_is_present_in_vbt(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- union child_device_config *p_child;
+ struct child_device_config *p_child;
int i, ret;
if (!dev_priv->vbt.child_dev_num)
@@ -1536,13 +1530,13 @@ static int tv_is_present_in_vbt(struct drm_device *dev)
/*
* If the device type is not TV, continue.
*/
- if (p_child->old.device_type != DEVICE_TYPE_INT_TV &&
- p_child->old.device_type != DEVICE_TYPE_TV)
+ if (p_child->device_type != DEVICE_TYPE_INT_TV &&
+ p_child->device_type != DEVICE_TYPE_TV)
continue;
/* Only when the addin_offset is non-zero, it is regarded
* as present.
*/
- if (p_child->old.addin_offset) {
+ if (p_child->addin_offset) {
ret = 1;
break;
}
@@ -1596,12 +1590,12 @@ intel_tv_init(struct drm_device *dev)
(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
return;
- intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
+ intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL);
if (!intel_tv) {
return;
}
- intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+ intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_tv);
return;
@@ -1628,7 +1622,6 @@ intel_tv_init(struct drm_device *dev)
DRM_MODE_ENCODER_TVDAC);
intel_encoder->compute_config = intel_tv_compute_config;
- intel_encoder->get_config = intel_tv_get_config;
intel_encoder->mode_set = intel_tv_mode_set;
intel_encoder->enable = intel_enable_tv;
intel_encoder->disable = intel_disable_tv;
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 0b02078..8649f1c 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -93,7 +93,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
{
u32 forcewake_ack;
- if (IS_HASWELL(dev_priv->dev) || IS_GEN8(dev_priv->dev))
+ if (IS_HASWELL(dev_priv->dev))
forcewake_ack = FORCEWAKE_ACK_HSW;
else
forcewake_ack = FORCEWAKE_MT_ACK;
@@ -112,8 +112,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
/* WaRsForcewakeWaitTC0:ivb,hsw */
- if (INTEL_INFO(dev_priv->dev)->gen < 8)
- __gen6_gt_wait_for_thread_c0(dev_priv);
+ __gen6_gt_wait_for_thread_c0(dev_priv);
}
static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
@@ -205,74 +204,82 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv)
gen6_gt_check_fifodbg(dev_priv);
}
-static void gen6_force_wake_work(struct work_struct *work)
+void intel_uncore_early_sanitize(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv =
- container_of(work, typeof(*dev_priv), uncore.force_wake_work.work);
- unsigned long irqflags;
+ struct drm_i915_private *dev_priv = dev->dev_private;
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- if (--dev_priv->uncore.forcewake_count == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv);
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+ if (HAS_FPGA_DBG_UNCLAIMED(dev))
+ __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
}
-static void intel_uncore_forcewake_reset(struct drm_device *dev)
+void intel_uncore_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
if (IS_VALLEYVIEW(dev)) {
- vlv_force_wake_reset(dev_priv);
- } else if (INTEL_INFO(dev)->gen >= 6) {
- __gen6_gt_force_wake_reset(dev_priv);
- if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
- __gen6_gt_force_wake_mt_reset(dev_priv);
+ dev_priv->uncore.funcs.force_wake_get = vlv_force_wake_get;
+ dev_priv->uncore.funcs.force_wake_put = vlv_force_wake_put;
+ } else if (IS_HASWELL(dev)) {
+ dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get;
+ dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put;
+ } else if (IS_IVYBRIDGE(dev)) {
+ u32 ecobus;
+
+ /* IVB configs may use multi-threaded forcewake */
+
+ /* A small trick here - if the bios hasn't configured
+ * MT forcewake, and if the device is in RC6, then
+ * force_wake_mt_get will not wake the device and the
+ * ECOBUS read will return zero. Which will be
+ * (correctly) interpreted by the test below as MT
+ * forcewake being disabled.
+ */
+ mutex_lock(&dev->struct_mutex);
+ __gen6_gt_force_wake_mt_get(dev_priv);
+ ecobus = __raw_i915_read32(dev_priv, ECOBUS);
+ __gen6_gt_force_wake_mt_put(dev_priv);
+ mutex_unlock(&dev->struct_mutex);
+
+ if (ecobus & FORCEWAKE_MT_ENABLE) {
+ dev_priv->uncore.funcs.force_wake_get =
+ __gen6_gt_force_wake_mt_get;
+ dev_priv->uncore.funcs.force_wake_put =
+ __gen6_gt_force_wake_mt_put;
+ } else {
+ DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
+ DRM_INFO("when using vblank-synced partial screen updates.\n");
+ dev_priv->uncore.funcs.force_wake_get =
+ __gen6_gt_force_wake_get;
+ dev_priv->uncore.funcs.force_wake_put =
+ __gen6_gt_force_wake_put;
+ }
+ } else if (IS_GEN6(dev)) {
+ dev_priv->uncore.funcs.force_wake_get =
+ __gen6_gt_force_wake_get;
+ dev_priv->uncore.funcs.force_wake_put =
+ __gen6_gt_force_wake_put;
}
}
-void intel_uncore_early_sanitize(struct drm_device *dev)
+static void intel_uncore_forcewake_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (HAS_FPGA_DBG_UNCLAIMED(dev))
- __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
-
- if (IS_HASWELL(dev) &&
- (__raw_i915_read32(dev_priv, HSW_EDRAM_PRESENT) == 1)) {
- /* The docs do not explain exactly how the calculation can be
- * made. It is somewhat guessable, but for now, it's always
- * 128MB.
- * NB: We can't write IDICR yet because we do not have gt funcs
- * set up */
- dev_priv->ellc_size = 128;
- DRM_INFO("Found %zuMB of eLLC\n", dev_priv->ellc_size);
+ if (IS_VALLEYVIEW(dev)) {
+ vlv_force_wake_reset(dev_priv);
+ } else if (INTEL_INFO(dev)->gen >= 6) {
+ __gen6_gt_force_wake_reset(dev_priv);
+ if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+ __gen6_gt_force_wake_mt_reset(dev_priv);
}
-
- intel_uncore_forcewake_reset(dev);
}
void intel_uncore_sanitize(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 reg_val;
-
intel_uncore_forcewake_reset(dev);
/* BIOS often leaves RC6 enabled, but disable it for hw init */
intel_disable_gt_powersave(dev);
-
- /* Turn off power gate, require especially for the BIOS less system */
- if (IS_VALLEYVIEW(dev)) {
-
- mutex_lock(&dev_priv->rps.hw_lock);
- reg_val = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS);
-
- if (reg_val & (RENDER_PWRGT | MEDIA_PWRGT | DISP2D_PWRGT))
- vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, 0x0);
-
- mutex_unlock(&dev_priv->rps.hw_lock);
-
- }
}
/*
@@ -285,9 +292,6 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
unsigned long irqflags;
- if (!dev_priv->uncore.funcs.force_wake_get)
- return;
-
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
if (dev_priv->uncore.forcewake_count++ == 0)
dev_priv->uncore.funcs.force_wake_get(dev_priv);
@@ -301,22 +305,17 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
unsigned long irqflags;
- if (!dev_priv->uncore.funcs.force_wake_put)
- return;
-
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- if (--dev_priv->uncore.forcewake_count == 0) {
- dev_priv->uncore.forcewake_count++;
- mod_delayed_work(dev_priv->wq,
- &dev_priv->uncore.force_wake_work,
- 1);
- }
+ if (--dev_priv->uncore.forcewake_count == 0)
+ dev_priv->uncore.funcs.force_wake_put(dev_priv);
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
- ((reg) < 0x40000 && (reg) != FORCEWAKE)
+ ((HAS_FORCE_WAKE((dev_priv)->dev)) && \
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE))
static void
ilk_dummy_write(struct drm_i915_private *dev_priv)
@@ -330,7 +329,8 @@ ilk_dummy_write(struct drm_i915_private *dev_priv)
static void
hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg)
{
- if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) {
+ if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) &&
+ (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) {
DRM_ERROR("Unknown unclaimed register before writing to %x\n",
reg);
__raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
@@ -340,43 +340,20 @@ hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg)
static void
hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg)
{
- if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) {
+ if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) &&
+ (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) {
DRM_ERROR("Unclaimed write to %x\n", reg);
__raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
}
}
-#define REG_READ_HEADER(x) \
+#define __i915_read(x) \
+u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg, bool trace) { \
unsigned long irqflags; \
u##x val = 0; \
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
-
-#define REG_READ_FOOTER \
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
- trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
- return val
-
-#define __gen4_read(x) \
-static u##x \
-gen4_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- REG_READ_HEADER(x); \
- val = __raw_i915_read##x(dev_priv, reg); \
- REG_READ_FOOTER; \
-}
-
-#define __gen5_read(x) \
-static u##x \
-gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- REG_READ_HEADER(x); \
- ilk_dummy_write(dev_priv); \
- val = __raw_i915_read##x(dev_priv, reg); \
- REG_READ_FOOTER; \
-}
-
-#define __gen6_read(x) \
-static u##x \
-gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- REG_READ_HEADER(x); \
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \
+ if (dev_priv->info->gen == 5) \
+ ilk_dummy_write(dev_priv); \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
if (dev_priv->uncore.forcewake_count == 0) \
dev_priv->uncore.funcs.force_wake_get(dev_priv); \
@@ -386,73 +363,28 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
} else { \
val = __raw_i915_read##x(dev_priv, reg); \
} \
- REG_READ_FOOTER; \
-}
-
-__gen6_read(8)
-__gen6_read(16)
-__gen6_read(32)
-__gen6_read(64)
-__gen5_read(8)
-__gen5_read(16)
-__gen5_read(32)
-__gen5_read(64)
-__gen4_read(8)
-__gen4_read(16)
-__gen4_read(32)
-__gen4_read(64)
-
-#undef __gen6_read
-#undef __gen5_read
-#undef __gen4_read
-#undef REG_READ_FOOTER
-#undef REG_READ_HEADER
-
-#define REG_WRITE_HEADER \
- unsigned long irqflags; \
- trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
-
-#define __gen4_write(x) \
-static void \
-gen4_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- REG_WRITE_HEADER; \
- __raw_i915_write##x(dev_priv, reg, val); \
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
+ trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
+ return val; \
}
-#define __gen5_write(x) \
-static void \
-gen5_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- REG_WRITE_HEADER; \
- ilk_dummy_write(dev_priv); \
- __raw_i915_write##x(dev_priv, reg, val); \
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
-}
+__i915_read(8)
+__i915_read(16)
+__i915_read(32)
+__i915_read(64)
+#undef __i915_read
-#define __gen6_write(x) \
-static void \
-gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- u32 __fifo_ret = 0; \
- REG_WRITE_HEADER; \
- if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
- __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
- } \
- __raw_i915_write##x(dev_priv, reg, val); \
- if (unlikely(__fifo_ret)) { \
- gen6_gt_check_fifodbg(dev_priv); \
- } \
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
-}
-
-#define __hsw_write(x) \
-static void \
-hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
+#define __i915_write(x) \
+void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val, bool trace) { \
+ unsigned long irqflags; \
u32 __fifo_ret = 0; \
- REG_WRITE_HEADER; \
+ trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
} \
+ if (dev_priv->info->gen == 5) \
+ ilk_dummy_write(dev_priv); \
hsw_unclaimed_reg_clear(dev_priv, reg); \
__raw_i915_write##x(dev_priv, reg, val); \
if (unlikely(__fifo_ret)) { \
@@ -461,185 +393,11 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
hsw_unclaimed_reg_check(dev_priv, reg); \
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
}
-
-static const u32 gen8_shadowed_regs[] = {
- FORCEWAKE_MT,
- GEN6_RPNSWREQ,
- GEN6_RC_VIDEO_FREQ,
- RING_TAIL(RENDER_RING_BASE),
- RING_TAIL(GEN6_BSD_RING_BASE),
- RING_TAIL(VEBOX_RING_BASE),
- RING_TAIL(BLT_RING_BASE),
- /* TODO: Other registers are not yet used */
-};
-
-static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(gen8_shadowed_regs); i++)
- if (reg == gen8_shadowed_regs[i])
- return true;
-
- return false;
-}
-
-#define __gen8_write(x) \
-static void \
-gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- bool __needs_put = !is_gen8_shadowed(dev_priv, reg); \
- REG_WRITE_HEADER; \
- if (__needs_put) { \
- dev_priv->uncore.funcs.force_wake_get(dev_priv); \
- } \
- __raw_i915_write##x(dev_priv, reg, val); \
- if (__needs_put) { \
- dev_priv->uncore.funcs.force_wake_put(dev_priv); \
- } \
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
-}
-
-__gen8_write(8)
-__gen8_write(16)
-__gen8_write(32)
-__gen8_write(64)
-__hsw_write(8)
-__hsw_write(16)
-__hsw_write(32)
-__hsw_write(64)
-__gen6_write(8)
-__gen6_write(16)
-__gen6_write(32)
-__gen6_write(64)
-__gen5_write(8)
-__gen5_write(16)
-__gen5_write(32)
-__gen5_write(64)
-__gen4_write(8)
-__gen4_write(16)
-__gen4_write(32)
-__gen4_write(64)
-
-#undef __gen8_write
-#undef __hsw_write
-#undef __gen6_write
-#undef __gen5_write
-#undef __gen4_write
-#undef REG_WRITE_HEADER
-
-void intel_uncore_init(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- INIT_DELAYED_WORK(&dev_priv->uncore.force_wake_work,
- gen6_force_wake_work);
-
- if (IS_VALLEYVIEW(dev)) {
- dev_priv->uncore.funcs.force_wake_get = vlv_force_wake_get;
- dev_priv->uncore.funcs.force_wake_put = vlv_force_wake_put;
- } else if (IS_HASWELL(dev) || IS_GEN8(dev)) {
- dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get;
- dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put;
- } else if (IS_IVYBRIDGE(dev)) {
- u32 ecobus;
-
- /* IVB configs may use multi-threaded forcewake */
-
- /* A small trick here - if the bios hasn't configured
- * MT forcewake, and if the device is in RC6, then
- * force_wake_mt_get will not wake the device and the
- * ECOBUS read will return zero. Which will be
- * (correctly) interpreted by the test below as MT
- * forcewake being disabled.
- */
- mutex_lock(&dev->struct_mutex);
- __gen6_gt_force_wake_mt_get(dev_priv);
- ecobus = __raw_i915_read32(dev_priv, ECOBUS);
- __gen6_gt_force_wake_mt_put(dev_priv);
- mutex_unlock(&dev->struct_mutex);
-
- if (ecobus & FORCEWAKE_MT_ENABLE) {
- dev_priv->uncore.funcs.force_wake_get =
- __gen6_gt_force_wake_mt_get;
- dev_priv->uncore.funcs.force_wake_put =
- __gen6_gt_force_wake_mt_put;
- } else {
- DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
- DRM_INFO("when using vblank-synced partial screen updates.\n");
- dev_priv->uncore.funcs.force_wake_get =
- __gen6_gt_force_wake_get;
- dev_priv->uncore.funcs.force_wake_put =
- __gen6_gt_force_wake_put;
- }
- } else if (IS_GEN6(dev)) {
- dev_priv->uncore.funcs.force_wake_get =
- __gen6_gt_force_wake_get;
- dev_priv->uncore.funcs.force_wake_put =
- __gen6_gt_force_wake_put;
- }
-
- switch (INTEL_INFO(dev)->gen) {
- default:
- dev_priv->uncore.funcs.mmio_writeb = gen8_write8;
- dev_priv->uncore.funcs.mmio_writew = gen8_write16;
- dev_priv->uncore.funcs.mmio_writel = gen8_write32;
- dev_priv->uncore.funcs.mmio_writeq = gen8_write64;
- dev_priv->uncore.funcs.mmio_readb = gen6_read8;
- dev_priv->uncore.funcs.mmio_readw = gen6_read16;
- dev_priv->uncore.funcs.mmio_readl = gen6_read32;
- dev_priv->uncore.funcs.mmio_readq = gen6_read64;
- break;
- case 7:
- case 6:
- if (IS_HASWELL(dev)) {
- dev_priv->uncore.funcs.mmio_writeb = hsw_write8;
- dev_priv->uncore.funcs.mmio_writew = hsw_write16;
- dev_priv->uncore.funcs.mmio_writel = hsw_write32;
- dev_priv->uncore.funcs.mmio_writeq = hsw_write64;
- } else {
- dev_priv->uncore.funcs.mmio_writeb = gen6_write8;
- dev_priv->uncore.funcs.mmio_writew = gen6_write16;
- dev_priv->uncore.funcs.mmio_writel = gen6_write32;
- dev_priv->uncore.funcs.mmio_writeq = gen6_write64;
- }
- dev_priv->uncore.funcs.mmio_readb = gen6_read8;
- dev_priv->uncore.funcs.mmio_readw = gen6_read16;
- dev_priv->uncore.funcs.mmio_readl = gen6_read32;
- dev_priv->uncore.funcs.mmio_readq = gen6_read64;
- break;
- case 5:
- dev_priv->uncore.funcs.mmio_writeb = gen5_write8;
- dev_priv->uncore.funcs.mmio_writew = gen5_write16;
- dev_priv->uncore.funcs.mmio_writel = gen5_write32;
- dev_priv->uncore.funcs.mmio_writeq = gen5_write64;
- dev_priv->uncore.funcs.mmio_readb = gen5_read8;
- dev_priv->uncore.funcs.mmio_readw = gen5_read16;
- dev_priv->uncore.funcs.mmio_readl = gen5_read32;
- dev_priv->uncore.funcs.mmio_readq = gen5_read64;
- break;
- case 4:
- case 3:
- case 2:
- dev_priv->uncore.funcs.mmio_writeb = gen4_write8;
- dev_priv->uncore.funcs.mmio_writew = gen4_write16;
- dev_priv->uncore.funcs.mmio_writel = gen4_write32;
- dev_priv->uncore.funcs.mmio_writeq = gen4_write64;
- dev_priv->uncore.funcs.mmio_readb = gen4_read8;
- dev_priv->uncore.funcs.mmio_readw = gen4_read16;
- dev_priv->uncore.funcs.mmio_readl = gen4_read32;
- dev_priv->uncore.funcs.mmio_readq = gen4_read64;
- break;
- }
-}
-
-void intel_uncore_fini(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- flush_delayed_work(&dev_priv->uncore.force_wake_work);
-
- /* Paranoia: make sure we have disabled everything before we exit. */
- intel_uncore_sanitize(dev);
-}
+__i915_write(8)
+__i915_write(16)
+__i915_write(32)
+__i915_write(64)
+#undef __i915_write
static const struct register_whitelist {
uint64_t offset;
@@ -687,6 +445,36 @@ int i915_reg_read_ioctl(struct drm_device *dev,
return 0;
}
+static int i8xx_do_reset(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (IS_I85X(dev))
+ return -ENODEV;
+
+ I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830);
+ POSTING_READ(D_STATE);
+
+ if (IS_I830(dev) || IS_845G(dev)) {
+ I915_WRITE(DEBUG_RESET_I830,
+ DEBUG_RESET_DISPLAY |
+ DEBUG_RESET_RENDER |
+ DEBUG_RESET_FULL);
+ POSTING_READ(DEBUG_RESET_I830);
+ msleep(1);
+
+ I915_WRITE(DEBUG_RESET_I830, 0);
+ POSTING_READ(DEBUG_RESET_I830);
+ }
+
+ msleep(1);
+
+ I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830);
+ POSTING_READ(D_STATE);
+
+ return 0;
+}
+
static int i965_reset_complete(struct drm_device *dev)
{
u8 gdrst;
@@ -788,6 +576,7 @@ int intel_gpu_reset(struct drm_device *dev)
case 6: return gen6_do_reset(dev);
case 5: return ironlake_do_reset(dev);
case 4: return i965_do_reset(dev);
+ case 2: return i8xx_do_reset(dev);
default: return -ENODEV;
}
}
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index 087db33..cc3166d 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -406,6 +406,11 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
+ dev->counters += 3;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+
ret = drm_vblank_init(dev, 1);
if (ret) {
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c
index 2b0ceb8..598c281 100644
--- a/drivers/gpu/drm/mga/mga_irq.c
+++ b/drivers/gpu/drm/mga/mga_irq.c
@@ -169,5 +169,5 @@ void mga_driver_irq_uninstall(struct drm_device *dev)
/* Disable *all* interrupts */
MGA_WRITE(MGA_IEN, 0);
- dev->irq_enabled = false;
+ dev->irq_enabled = 0;
}
diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index 3a1c5fb..b487cde 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -5,7 +5,6 @@ config DRM_MGAG200
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_TTM
help
This is a KMS driver for the MGA G200 server chips, it
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index f15ea3c..fcce7b2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -99,6 +99,7 @@ static struct drm_driver driver = {
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
+ .gem_init_object = mgag200_gem_init_object,
.gem_free_object = mgag200_gem_free_object,
.dumb_create = mgag200_dumb_create,
.dumb_map_offset = mgag200_dumb_mmap_offset,
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index cf11ee6..baaae19 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -260,6 +260,7 @@ int mgag200_driver_unload(struct drm_device *dev);
int mgag200_gem_create(struct drm_device *dev,
u32 size, bool iskernel,
struct drm_gem_object **obj);
+int mgag200_gem_init_object(struct drm_gem_object *obj);
int mgag200_dumb_create(struct drm_file *file,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index b1120cb..0f8b861 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -310,6 +310,12 @@ int mgag200_dumb_create(struct drm_file *file,
return 0;
}
+int mgag200_gem_init_object(struct drm_gem_object *obj)
+{
+ BUG();
+ return 0;
+}
+
void mgag200_bo_unref(struct mgag200_bo **bo)
{
struct ttm_buffer_object *tbo;
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index ee6ed63..503a414 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -765,6 +765,8 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc,
}
mgag200_bo_unreserve(bo);
+ DRM_INFO("mga base %llx\n", gpu_addr);
+
mga_set_start_address(crtc, (u32)gpu_addr);
return 0;
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index f39ab75..a06c19c 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -14,7 +14,6 @@ config DRM_MSM
config DRM_MSM_FBDEV
bool "Enable legacy fbdev support for MSM modesetting driver"
depends on DRM_MSM
- select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index e5fa12b..e179148 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -21,7 +21,6 @@ msm-y := \
msm_drv.o \
msm_fb.o \
msm_gem.o \
- msm_gem_prime.o \
msm_gem_submit.o \
msm_gpu.o \
msm_ringbuffer.o
diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
index 9588098..3546386 100644
--- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
@@ -4,16 +4,16 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 31003 bytes, from 2013-09-19 18:50:16)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48)
- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-10 00:52:33)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51983 bytes, from 2013-09-10 00:52:32)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -317,38 +317,6 @@ static inline uint32_t A2XX_RBBM_STATUS_CMDFIFO_AVAIL(uint32_t val)
#define A2XX_RBBM_STATUS_RB_CNTX_BUSY 0x40000000
#define A2XX_RBBM_STATUS_GUI_ACTIVE 0x80000000
-#define REG_A2XX_MH_ARBITER_CONFIG 0x00000a40
-#define A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT__MASK 0x0000003f
-#define A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT__SHIFT 0
-static inline uint32_t A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT(uint32_t val)
-{
- return ((val) << A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT__SHIFT) & A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT__MASK;
-}
-#define A2XX_MH_ARBITER_CONFIG_SAME_PAGE_GRANULARITY 0x00000040
-#define A2XX_MH_ARBITER_CONFIG_L1_ARB_ENABLE 0x00000080
-#define A2XX_MH_ARBITER_CONFIG_L1_ARB_HOLD_ENABLE 0x00000100
-#define A2XX_MH_ARBITER_CONFIG_L2_ARB_CONTROL 0x00000200
-#define A2XX_MH_ARBITER_CONFIG_PAGE_SIZE__MASK 0x00001c00
-#define A2XX_MH_ARBITER_CONFIG_PAGE_SIZE__SHIFT 10
-static inline uint32_t A2XX_MH_ARBITER_CONFIG_PAGE_SIZE(uint32_t val)
-{
- return ((val) << A2XX_MH_ARBITER_CONFIG_PAGE_SIZE__SHIFT) & A2XX_MH_ARBITER_CONFIG_PAGE_SIZE__MASK;
-}
-#define A2XX_MH_ARBITER_CONFIG_TC_REORDER_ENABLE 0x00002000
-#define A2XX_MH_ARBITER_CONFIG_TC_ARB_HOLD_ENABLE 0x00004000
-#define A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT_ENABLE 0x00008000
-#define A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT__MASK 0x003f0000
-#define A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT__SHIFT 16
-static inline uint32_t A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT(uint32_t val)
-{
- return ((val) << A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT__SHIFT) & A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT__MASK;
-}
-#define A2XX_MH_ARBITER_CONFIG_CP_CLNT_ENABLE 0x00400000
-#define A2XX_MH_ARBITER_CONFIG_VGT_CLNT_ENABLE 0x00800000
-#define A2XX_MH_ARBITER_CONFIG_TC_CLNT_ENABLE 0x01000000
-#define A2XX_MH_ARBITER_CONFIG_RB_CLNT_ENABLE 0x02000000
-#define A2XX_MH_ARBITER_CONFIG_PA_CLNT_ENABLE 0x04000000
-
#define REG_A2XX_A220_VSC_BIN_SIZE 0x00000c01
#define A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK 0x0000001f
#define A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT 0
diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
index d4afdf6..d183516 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
@@ -4,16 +4,16 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 31003 bytes, from 2013-09-19 18:50:16)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48)
- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-10 00:52:33)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51983 bytes, from 2013-09-10 00:52:32)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -637,12 +637,11 @@ static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_OFFSET(float val)
#define REG_A3XX_GRAS_SU_MODE_CONTROL 0x00002070
#define A3XX_GRAS_SU_MODE_CONTROL_CULL_FRONT 0x00000001
#define A3XX_GRAS_SU_MODE_CONTROL_CULL_BACK 0x00000002
-#define A3XX_GRAS_SU_MODE_CONTROL_FRONT_CW 0x00000004
-#define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK 0x000007f8
-#define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3
-static inline uint32_t A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val)
+#define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK 0x000007fc
+#define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 2
+static inline uint32_t A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(uint32_t val)
{
- return ((((uint32_t)(val * 4.0))) << A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK;
+ return ((val) << A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK;
}
#define A3XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800
@@ -746,7 +745,6 @@ static inline uint32_t A3XX_RB_RENDER_CONTROL_BIN_WIDTH(uint32_t val)
}
#define A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE 0x00001000
#define A3XX_RB_RENDER_CONTROL_ENABLE_GMEM 0x00002000
-#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST 0x00400000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK 0x07000000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT 24
static inline uint32_t A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(enum adreno_compare_func val)
@@ -769,19 +767,7 @@ static inline uint32_t A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(uint32_t val)
return ((val) << A3XX_RB_MSAA_CONTROL_SAMPLE_MASK__SHIFT) & A3XX_RB_MSAA_CONTROL_SAMPLE_MASK__MASK;
}
-#define REG_A3XX_RB_ALPHA_REF 0x000020c3
-#define A3XX_RB_ALPHA_REF_UINT__MASK 0x0000ff00
-#define A3XX_RB_ALPHA_REF_UINT__SHIFT 8
-static inline uint32_t A3XX_RB_ALPHA_REF_UINT(uint32_t val)
-{
- return ((val) << A3XX_RB_ALPHA_REF_UINT__SHIFT) & A3XX_RB_ALPHA_REF_UINT__MASK;
-}
-#define A3XX_RB_ALPHA_REF_FLOAT__MASK 0xffff0000
-#define A3XX_RB_ALPHA_REF_FLOAT__SHIFT 16
-static inline uint32_t A3XX_RB_ALPHA_REF_FLOAT(float val)
-{
- return ((util_float_to_half(val)) << A3XX_RB_ALPHA_REF_FLOAT__SHIFT) & A3XX_RB_ALPHA_REF_FLOAT__MASK;
-}
+#define REG_A3XX_UNKNOWN_20C3 0x000020c3
static inline uint32_t REG_A3XX_RB_MRT(uint32_t i0) { return 0x000020c4 + 0x4*i0; }
@@ -1016,7 +1002,7 @@ static inline uint32_t A3XX_RB_COPY_DEST_INFO_ENDIAN(enum adreno_rb_surface_endi
#define REG_A3XX_RB_DEPTH_CONTROL 0x00002100
#define A3XX_RB_DEPTH_CONTROL_Z_ENABLE 0x00000002
#define A3XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE 0x00000004
-#define A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE 0x00000008
+#define A3XX_RB_DEPTH_CONTROL_EARLY_Z_ENABLE 0x00000008
#define A3XX_RB_DEPTH_CONTROL_ZFUNC__MASK 0x00000070
#define A3XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT 4
static inline uint32_t A3XX_RB_DEPTH_CONTROL_ZFUNC(enum adreno_compare_func val)
@@ -1052,8 +1038,7 @@ static inline uint32_t A3XX_RB_DEPTH_PITCH(uint32_t val)
#define REG_A3XX_RB_STENCIL_CONTROL 0x00002104
#define A3XX_RB_STENCIL_CONTROL_STENCIL_ENABLE 0x00000001
-#define A3XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF 0x00000002
-#define A3XX_RB_STENCIL_CONTROL_STENCIL_READ 0x00000004
+#define A3XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF 0x00000004
#define A3XX_RB_STENCIL_CONTROL_FUNC__MASK 0x00000700
#define A3XX_RB_STENCIL_CONTROL_FUNC__SHIFT 8
static inline uint32_t A3XX_RB_STENCIL_CONTROL_FUNC(enum adreno_compare_func val)
@@ -2089,7 +2074,6 @@ static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(enum a3xx_cache_op
#define REG_A3XX_TP_PERFCOUNTER5_SELECT 0x00000f09
#define REG_A3XX_TEX_SAMP_0 0x00000000
-#define A3XX_TEX_SAMP_0_MIPFILTER_LINEAR 0x00000002
#define A3XX_TEX_SAMP_0_XY_MAG__MASK 0x0000000c
#define A3XX_TEX_SAMP_0_XY_MAG__SHIFT 2
static inline uint32_t A3XX_TEX_SAMP_0_XY_MAG(enum a3xx_tex_filter val)
@@ -2150,12 +2134,6 @@ static inline uint32_t A3XX_TEX_CONST_0_SWIZ_W(enum a3xx_tex_swiz val)
{
return ((val) << A3XX_TEX_CONST_0_SWIZ_W__SHIFT) & A3XX_TEX_CONST_0_SWIZ_W__MASK;
}
-#define A3XX_TEX_CONST_0_MIPLVLS__MASK 0x000f0000
-#define A3XX_TEX_CONST_0_MIPLVLS__SHIFT 16
-static inline uint32_t A3XX_TEX_CONST_0_MIPLVLS(uint32_t val)
-{
- return ((val) << A3XX_TEX_CONST_0_MIPLVLS__SHIFT) & A3XX_TEX_CONST_0_MIPLVLS__MASK;
-}
#define A3XX_TEX_CONST_0_FMT__MASK 0x1fc00000
#define A3XX_TEX_CONST_0_FMT__SHIFT 22
static inline uint32_t A3XX_TEX_CONST_0_FMT(enum a3xx_tex_fmt val)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
index 33dcc60..61979d4 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
@@ -4,16 +4,16 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 31003 bytes, from 2013-09-19 18:50:16)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48)
- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-10 00:52:33)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51983 bytes, from 2013-09-10 00:52:32)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
index 259ad70..94c13f4 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
@@ -4,16 +4,16 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 31003 bytes, from 2013-09-19 18:50:16)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48)
- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-10 00:52:33)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51983 bytes, from 2013-09-10 00:52:32)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index 6d4c62b..6f8396b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -4,13 +4,13 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 595 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-10-07 16:36:48)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-08-16 22:16:36)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
index d1df38b..aefc1b8 100644
--- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
+++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
@@ -4,13 +4,13 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 595 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-10-07 16:36:48)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-08-16 22:16:36)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h
index 0030a11..a225e81 100644
--- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h
+++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h
@@ -4,13 +4,13 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 595 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-10-07 16:36:48)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-08-16 22:16:36)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
index 4e939f8..f5fa486 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
@@ -4,13 +4,13 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 595 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-10-07 16:36:48)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-08-16 22:16:36)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
index dbde4f6..bee3636 100644
--- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
+++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
@@ -4,13 +4,13 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 595 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-10-07 16:36:48)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-08-16 22:16:36)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp4/mdp4.xml.h
index 9908ffe..bbeeebe 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4.xml.h
+++ b/drivers/gpu/drm/msm/mdp4/mdp4.xml.h
@@ -4,13 +4,13 @@
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 595 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-10-07 16:36:48)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-08-16 22:16:36)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
@@ -42,28 +42,28 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-enum mdp4_bpc {
+enum mpd4_bpc {
BPC1 = 0,
BPC5 = 1,
BPC6 = 2,
BPC8 = 3,
};
-enum mdp4_bpc_alpha {
+enum mpd4_bpc_alpha {
BPC1A = 0,
BPC4A = 1,
BPC6A = 2,
BPC8A = 3,
};
-enum mdp4_alpha_type {
+enum mpd4_alpha_type {
FG_CONST = 0,
BG_CONST = 1,
FG_PIXEL = 2,
BG_PIXEL = 3,
};
-enum mdp4_pipe {
+enum mpd4_pipe {
VG1 = 0,
VG2 = 1,
RGB1 = 2,
@@ -73,13 +73,13 @@ enum mdp4_pipe {
VG4 = 6,
};
-enum mdp4_mixer {
+enum mpd4_mixer {
MIXER0 = 0,
MIXER1 = 1,
MIXER2 = 2,
};
-enum mdp4_mixer_stage_id {
+enum mpd4_mixer_stage_id {
STAGE_UNUSED = 0,
STAGE_BASE = 1,
STAGE0 = 2,
@@ -194,56 +194,56 @@ static inline uint32_t MDP4_DISP_INTF_SEL_EXT(enum mdp4_intf val)
#define REG_MDP4_LAYERMIXER2_IN_CFG 0x000100f0
#define MDP4_LAYERMIXER2_IN_CFG_PIPE0__MASK 0x00000007
#define MDP4_LAYERMIXER2_IN_CFG_PIPE0__SHIFT 0
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE0(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE0(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE0__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE0__MASK;
}
#define MDP4_LAYERMIXER2_IN_CFG_PIPE0_MIXER1 0x00000008
#define MDP4_LAYERMIXER2_IN_CFG_PIPE1__MASK 0x00000070
#define MDP4_LAYERMIXER2_IN_CFG_PIPE1__SHIFT 4
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE1(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE1(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE1__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE1__MASK;
}
#define MDP4_LAYERMIXER2_IN_CFG_PIPE1_MIXER1 0x00000080
#define MDP4_LAYERMIXER2_IN_CFG_PIPE2__MASK 0x00000700
#define MDP4_LAYERMIXER2_IN_CFG_PIPE2__SHIFT 8
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE2(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE2(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE2__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE2__MASK;
}
#define MDP4_LAYERMIXER2_IN_CFG_PIPE2_MIXER1 0x00000800
#define MDP4_LAYERMIXER2_IN_CFG_PIPE3__MASK 0x00007000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE3__SHIFT 12
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE3(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE3(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE3__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE3__MASK;
}
#define MDP4_LAYERMIXER2_IN_CFG_PIPE3_MIXER1 0x00008000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE4__MASK 0x00070000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE4__SHIFT 16
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE4(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE4(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE4__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE4__MASK;
}
#define MDP4_LAYERMIXER2_IN_CFG_PIPE4_MIXER1 0x00080000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE5__MASK 0x00700000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE5__SHIFT 20
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE5(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE5(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE5__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE5__MASK;
}
#define MDP4_LAYERMIXER2_IN_CFG_PIPE5_MIXER1 0x00800000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE6__MASK 0x07000000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE6__SHIFT 24
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE6(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE6(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE6__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE6__MASK;
}
#define MDP4_LAYERMIXER2_IN_CFG_PIPE6_MIXER1 0x08000000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE7__MASK 0x70000000
#define MDP4_LAYERMIXER2_IN_CFG_PIPE7__SHIFT 28
-static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE7(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE7(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE7__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE7__MASK;
}
@@ -254,56 +254,56 @@ static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE7(enum mdp4_mixer_stage_id va
#define REG_MDP4_LAYERMIXER_IN_CFG 0x00010100
#define MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK 0x00000007
#define MDP4_LAYERMIXER_IN_CFG_PIPE0__SHIFT 0
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE0(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE0(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE0__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK;
}
#define MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1 0x00000008
#define MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK 0x00000070
#define MDP4_LAYERMIXER_IN_CFG_PIPE1__SHIFT 4
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE1(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE1(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE1__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK;
}
#define MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1 0x00000080
#define MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK 0x00000700
#define MDP4_LAYERMIXER_IN_CFG_PIPE2__SHIFT 8
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE2(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE2(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE2__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK;
}
#define MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1 0x00000800
#define MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK 0x00007000
#define MDP4_LAYERMIXER_IN_CFG_PIPE3__SHIFT 12
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE3(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE3(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE3__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK;
}
#define MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1 0x00008000
#define MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK 0x00070000
#define MDP4_LAYERMIXER_IN_CFG_PIPE4__SHIFT 16
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE4(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE4(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE4__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK;
}
#define MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1 0x00080000
#define MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK 0x00700000
#define MDP4_LAYERMIXER_IN_CFG_PIPE5__SHIFT 20
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE5(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE5(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE5__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK;
}
#define MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1 0x00800000
#define MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK 0x07000000
#define MDP4_LAYERMIXER_IN_CFG_PIPE6__SHIFT 24
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE6(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE6(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE6__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK;
}
#define MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1 0x08000000
#define MDP4_LAYERMIXER_IN_CFG_PIPE7__MASK 0x70000000
#define MDP4_LAYERMIXER_IN_CFG_PIPE7__SHIFT 28
-static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE7(enum mdp4_mixer_stage_id val)
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE7(enum mpd4_mixer_stage_id val)
{
return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE7__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE7__MASK;
}
@@ -369,7 +369,7 @@ static inline uint32_t REG_MDP4_OVLP_STAGE(uint32_t i0, uint32_t i1) { return 0x
static inline uint32_t REG_MDP4_OVLP_STAGE_OP(uint32_t i0, uint32_t i1) { return 0x00000000 + __offset_OVLP(i0) + __offset_STAGE(i1); }
#define MDP4_OVLP_STAGE_OP_FG_ALPHA__MASK 0x00000003
#define MDP4_OVLP_STAGE_OP_FG_ALPHA__SHIFT 0
-static inline uint32_t MDP4_OVLP_STAGE_OP_FG_ALPHA(enum mdp4_alpha_type val)
+static inline uint32_t MDP4_OVLP_STAGE_OP_FG_ALPHA(enum mpd4_alpha_type val)
{
return ((val) << MDP4_OVLP_STAGE_OP_FG_ALPHA__SHIFT) & MDP4_OVLP_STAGE_OP_FG_ALPHA__MASK;
}
@@ -377,7 +377,7 @@ static inline uint32_t MDP4_OVLP_STAGE_OP_FG_ALPHA(enum mdp4_alpha_type val)
#define MDP4_OVLP_STAGE_OP_FG_MOD_ALPHA 0x00000008
#define MDP4_OVLP_STAGE_OP_BG_ALPHA__MASK 0x00000030
#define MDP4_OVLP_STAGE_OP_BG_ALPHA__SHIFT 4
-static inline uint32_t MDP4_OVLP_STAGE_OP_BG_ALPHA(enum mdp4_alpha_type val)
+static inline uint32_t MDP4_OVLP_STAGE_OP_BG_ALPHA(enum mpd4_alpha_type val)
{
return ((val) << MDP4_OVLP_STAGE_OP_BG_ALPHA__SHIFT) & MDP4_OVLP_STAGE_OP_BG_ALPHA__MASK;
}
@@ -472,19 +472,19 @@ static inline uint32_t REG_MDP4_DMA(enum mdp4_dma i0) { return 0x00000000 + __of
static inline uint32_t REG_MDP4_DMA_CONFIG(enum mdp4_dma i0) { return 0x00000000 + __offset_DMA(i0); }
#define MDP4_DMA_CONFIG_G_BPC__MASK 0x00000003
#define MDP4_DMA_CONFIG_G_BPC__SHIFT 0
-static inline uint32_t MDP4_DMA_CONFIG_G_BPC(enum mdp4_bpc val)
+static inline uint32_t MDP4_DMA_CONFIG_G_BPC(enum mpd4_bpc val)
{
return ((val) << MDP4_DMA_CONFIG_G_BPC__SHIFT) & MDP4_DMA_CONFIG_G_BPC__MASK;
}
#define MDP4_DMA_CONFIG_B_BPC__MASK 0x0000000c
#define MDP4_DMA_CONFIG_B_BPC__SHIFT 2
-static inline uint32_t MDP4_DMA_CONFIG_B_BPC(enum mdp4_bpc val)
+static inline uint32_t MDP4_DMA_CONFIG_B_BPC(enum mpd4_bpc val)
{
return ((val) << MDP4_DMA_CONFIG_B_BPC__SHIFT) & MDP4_DMA_CONFIG_B_BPC__MASK;
}
#define MDP4_DMA_CONFIG_R_BPC__MASK 0x00000030
#define MDP4_DMA_CONFIG_R_BPC__SHIFT 4
-static inline uint32_t MDP4_DMA_CONFIG_R_BPC(enum mdp4_bpc val)
+static inline uint32_t MDP4_DMA_CONFIG_R_BPC(enum mpd4_bpc val)
{
return ((val) << MDP4_DMA_CONFIG_R_BPC__SHIFT) & MDP4_DMA_CONFIG_R_BPC__MASK;
}
@@ -601,9 +601,9 @@ static inline uint32_t REG_MDP4_DMA_CSC_POST_LV(enum mdp4_dma i0, uint32_t i1) {
static inline uint32_t REG_MDP4_DMA_CSC_POST_LV_VAL(enum mdp4_dma i0, uint32_t i1) { return 0x00003680 + __offset_DMA(i0) + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE(enum mdp4_pipe i0) { return 0x00020000 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE(enum mpd4_pipe i0) { return 0x00020000 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_SRC_SIZE(enum mdp4_pipe i0) { return 0x00020000 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRC_SIZE(enum mpd4_pipe i0) { return 0x00020000 + 0x10000*i0; }
#define MDP4_PIPE_SRC_SIZE_HEIGHT__MASK 0xffff0000
#define MDP4_PIPE_SRC_SIZE_HEIGHT__SHIFT 16
static inline uint32_t MDP4_PIPE_SRC_SIZE_HEIGHT(uint32_t val)
@@ -617,7 +617,7 @@ static inline uint32_t MDP4_PIPE_SRC_SIZE_WIDTH(uint32_t val)
return ((val) << MDP4_PIPE_SRC_SIZE_WIDTH__SHIFT) & MDP4_PIPE_SRC_SIZE_WIDTH__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_SRC_XY(enum mdp4_pipe i0) { return 0x00020004 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRC_XY(enum mpd4_pipe i0) { return 0x00020004 + 0x10000*i0; }
#define MDP4_PIPE_SRC_XY_Y__MASK 0xffff0000
#define MDP4_PIPE_SRC_XY_Y__SHIFT 16
static inline uint32_t MDP4_PIPE_SRC_XY_Y(uint32_t val)
@@ -631,7 +631,7 @@ static inline uint32_t MDP4_PIPE_SRC_XY_X(uint32_t val)
return ((val) << MDP4_PIPE_SRC_XY_X__SHIFT) & MDP4_PIPE_SRC_XY_X__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_DST_SIZE(enum mdp4_pipe i0) { return 0x00020008 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_DST_SIZE(enum mpd4_pipe i0) { return 0x00020008 + 0x10000*i0; }
#define MDP4_PIPE_DST_SIZE_HEIGHT__MASK 0xffff0000
#define MDP4_PIPE_DST_SIZE_HEIGHT__SHIFT 16
static inline uint32_t MDP4_PIPE_DST_SIZE_HEIGHT(uint32_t val)
@@ -645,7 +645,7 @@ static inline uint32_t MDP4_PIPE_DST_SIZE_WIDTH(uint32_t val)
return ((val) << MDP4_PIPE_DST_SIZE_WIDTH__SHIFT) & MDP4_PIPE_DST_SIZE_WIDTH__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_DST_XY(enum mdp4_pipe i0) { return 0x0002000c + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_DST_XY(enum mpd4_pipe i0) { return 0x0002000c + 0x10000*i0; }
#define MDP4_PIPE_DST_XY_Y__MASK 0xffff0000
#define MDP4_PIPE_DST_XY_Y__SHIFT 16
static inline uint32_t MDP4_PIPE_DST_XY_Y(uint32_t val)
@@ -659,13 +659,13 @@ static inline uint32_t MDP4_PIPE_DST_XY_X(uint32_t val)
return ((val) << MDP4_PIPE_DST_XY_X__SHIFT) & MDP4_PIPE_DST_XY_X__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_SRCP0_BASE(enum mdp4_pipe i0) { return 0x00020010 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRCP0_BASE(enum mpd4_pipe i0) { return 0x00020010 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_SRCP1_BASE(enum mdp4_pipe i0) { return 0x00020014 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRCP1_BASE(enum mpd4_pipe i0) { return 0x00020014 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_SRCP2_BASE(enum mdp4_pipe i0) { return 0x00020018 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRCP2_BASE(enum mpd4_pipe i0) { return 0x00020018 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_A(enum mdp4_pipe i0) { return 0x00020040 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_A(enum mpd4_pipe i0) { return 0x00020040 + 0x10000*i0; }
#define MDP4_PIPE_SRC_STRIDE_A_P0__MASK 0x0000ffff
#define MDP4_PIPE_SRC_STRIDE_A_P0__SHIFT 0
static inline uint32_t MDP4_PIPE_SRC_STRIDE_A_P0(uint32_t val)
@@ -679,7 +679,7 @@ static inline uint32_t MDP4_PIPE_SRC_STRIDE_A_P1(uint32_t val)
return ((val) << MDP4_PIPE_SRC_STRIDE_A_P1__SHIFT) & MDP4_PIPE_SRC_STRIDE_A_P1__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_B(enum mdp4_pipe i0) { return 0x00020044 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_B(enum mpd4_pipe i0) { return 0x00020044 + 0x10000*i0; }
#define MDP4_PIPE_SRC_STRIDE_B_P2__MASK 0x0000ffff
#define MDP4_PIPE_SRC_STRIDE_B_P2__SHIFT 0
static inline uint32_t MDP4_PIPE_SRC_STRIDE_B_P2(uint32_t val)
@@ -693,7 +693,7 @@ static inline uint32_t MDP4_PIPE_SRC_STRIDE_B_P3(uint32_t val)
return ((val) << MDP4_PIPE_SRC_STRIDE_B_P3__SHIFT) & MDP4_PIPE_SRC_STRIDE_B_P3__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_FRAME_SIZE(enum mdp4_pipe i0) { return 0x00020048 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_FRAME_SIZE(enum mpd4_pipe i0) { return 0x00020048 + 0x10000*i0; }
#define MDP4_PIPE_FRAME_SIZE_HEIGHT__MASK 0xffff0000
#define MDP4_PIPE_FRAME_SIZE_HEIGHT__SHIFT 16
static inline uint32_t MDP4_PIPE_FRAME_SIZE_HEIGHT(uint32_t val)
@@ -707,28 +707,28 @@ static inline uint32_t MDP4_PIPE_FRAME_SIZE_WIDTH(uint32_t val)
return ((val) << MDP4_PIPE_FRAME_SIZE_WIDTH__SHIFT) & MDP4_PIPE_FRAME_SIZE_WIDTH__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_SRC_FORMAT(enum mdp4_pipe i0) { return 0x00020050 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRC_FORMAT(enum mpd4_pipe i0) { return 0x00020050 + 0x10000*i0; }
#define MDP4_PIPE_SRC_FORMAT_G_BPC__MASK 0x00000003
#define MDP4_PIPE_SRC_FORMAT_G_BPC__SHIFT 0
-static inline uint32_t MDP4_PIPE_SRC_FORMAT_G_BPC(enum mdp4_bpc val)
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_G_BPC(enum mpd4_bpc val)
{
return ((val) << MDP4_PIPE_SRC_FORMAT_G_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_G_BPC__MASK;
}
#define MDP4_PIPE_SRC_FORMAT_B_BPC__MASK 0x0000000c
#define MDP4_PIPE_SRC_FORMAT_B_BPC__SHIFT 2
-static inline uint32_t MDP4_PIPE_SRC_FORMAT_B_BPC(enum mdp4_bpc val)
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_B_BPC(enum mpd4_bpc val)
{
return ((val) << MDP4_PIPE_SRC_FORMAT_B_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_B_BPC__MASK;
}
#define MDP4_PIPE_SRC_FORMAT_R_BPC__MASK 0x00000030
#define MDP4_PIPE_SRC_FORMAT_R_BPC__SHIFT 4
-static inline uint32_t MDP4_PIPE_SRC_FORMAT_R_BPC(enum mdp4_bpc val)
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_R_BPC(enum mpd4_bpc val)
{
return ((val) << MDP4_PIPE_SRC_FORMAT_R_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_R_BPC__MASK;
}
#define MDP4_PIPE_SRC_FORMAT_A_BPC__MASK 0x000000c0
#define MDP4_PIPE_SRC_FORMAT_A_BPC__SHIFT 6
-static inline uint32_t MDP4_PIPE_SRC_FORMAT_A_BPC(enum mdp4_bpc_alpha val)
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_A_BPC(enum mpd4_bpc_alpha val)
{
return ((val) << MDP4_PIPE_SRC_FORMAT_A_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_A_BPC__MASK;
}
@@ -750,7 +750,7 @@ static inline uint32_t MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(uint32_t val)
#define MDP4_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000
#define MDP4_PIPE_SRC_FORMAT_SOLID_FILL 0x00400000
-static inline uint32_t REG_MDP4_PIPE_SRC_UNPACK(enum mdp4_pipe i0) { return 0x00020054 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRC_UNPACK(enum mpd4_pipe i0) { return 0x00020054 + 0x10000*i0; }
#define MDP4_PIPE_SRC_UNPACK_ELEM0__MASK 0x000000ff
#define MDP4_PIPE_SRC_UNPACK_ELEM0__SHIFT 0
static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM0(uint32_t val)
@@ -776,7 +776,7 @@ static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM3(uint32_t val)
return ((val) << MDP4_PIPE_SRC_UNPACK_ELEM3__SHIFT) & MDP4_PIPE_SRC_UNPACK_ELEM3__MASK;
}
-static inline uint32_t REG_MDP4_PIPE_OP_MODE(enum mdp4_pipe i0) { return 0x00020058 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_OP_MODE(enum mpd4_pipe i0) { return 0x00020058 + 0x10000*i0; }
#define MDP4_PIPE_OP_MODE_SCALEX_EN 0x00000001
#define MDP4_PIPE_OP_MODE_SCALEY_EN 0x00000002
#define MDP4_PIPE_OP_MODE_SRC_YCBCR 0x00000200
@@ -789,36 +789,36 @@ static inline uint32_t REG_MDP4_PIPE_OP_MODE(enum mdp4_pipe i0) { return 0x00020
#define MDP4_PIPE_OP_MODE_DEINT_EN 0x00040000
#define MDP4_PIPE_OP_MODE_DEINT_ODD_REF 0x00080000
-static inline uint32_t REG_MDP4_PIPE_PHASEX_STEP(enum mdp4_pipe i0) { return 0x0002005c + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_PHASEX_STEP(enum mpd4_pipe i0) { return 0x0002005c + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_PHASEY_STEP(enum mdp4_pipe i0) { return 0x00020060 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_PHASEY_STEP(enum mpd4_pipe i0) { return 0x00020060 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_FETCH_CONFIG(enum mdp4_pipe i0) { return 0x00021004 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_FETCH_CONFIG(enum mpd4_pipe i0) { return 0x00021004 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_SOLID_COLOR(enum mdp4_pipe i0) { return 0x00021008 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SOLID_COLOR(enum mpd4_pipe i0) { return 0x00021008 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_CSC(enum mdp4_pipe i0) { return 0x00024000 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_CSC(enum mpd4_pipe i0) { return 0x00024000 + 0x10000*i0; }
-static inline uint32_t REG_MDP4_PIPE_CSC_MV(enum mdp4_pipe i0, uint32_t i1) { return 0x00024400 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_MV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024400 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_MV_VAL(enum mdp4_pipe i0, uint32_t i1) { return 0x00024400 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_MV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024400 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_PRE_BV(enum mdp4_pipe i0, uint32_t i1) { return 0x00024500 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_BV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024500 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_PRE_BV_VAL(enum mdp4_pipe i0, uint32_t i1) { return 0x00024500 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_BV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024500 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_POST_BV(enum mdp4_pipe i0, uint32_t i1) { return 0x00024580 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_BV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024580 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_POST_BV_VAL(enum mdp4_pipe i0, uint32_t i1) { return 0x00024580 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_BV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024580 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_PRE_LV(enum mdp4_pipe i0, uint32_t i1) { return 0x00024600 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_LV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024600 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_PRE_LV_VAL(enum mdp4_pipe i0, uint32_t i1) { return 0x00024600 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_LV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024600 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_POST_LV(enum mdp4_pipe i0, uint32_t i1) { return 0x00024680 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_LV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024680 + 0x10000*i0 + 0x4*i1; }
-static inline uint32_t REG_MDP4_PIPE_CSC_POST_LV_VAL(enum mdp4_pipe i0, uint32_t i1) { return 0x00024680 + 0x10000*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_LV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024680 + 0x10000*i0 + 0x4*i1; }
#define REG_MDP4_LCDC 0x000c0000
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
index 019d530..de6bea2 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
@@ -26,7 +26,6 @@ struct mdp4_crtc {
struct drm_crtc base;
char name[8];
struct drm_plane *plane;
- struct drm_plane *planes[8];
int id;
int ovlp;
enum mdp4_dma dma;
@@ -51,11 +50,7 @@ struct mdp4_crtc {
/* if there is a pending flip, these will be non-null: */
struct drm_pending_vblank_event *event;
- struct msm_fence_cb pageflip_cb;
-
-#define PENDING_CURSOR 0x1
-#define PENDING_FLIP 0x2
- atomic_t pending;
+ struct work_struct pageflip_work;
/* the fb that we currently hold a scanout ref to: */
struct drm_framebuffer *fb;
@@ -97,8 +92,7 @@ static void update_fb(struct drm_crtc *crtc, bool async,
}
}
-/* if file!=NULL, this is preclose potential cancel-flip path */
-static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
+static void complete_flip(struct drm_crtc *crtc, bool canceled)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct drm_device *dev = crtc->dev;
@@ -108,14 +102,11 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
spin_lock_irqsave(&dev->event_lock, flags);
event = mdp4_crtc->event;
if (event) {
- /* if regular vblank case (!file) or if cancel-flip from
- * preclose on file that requested flip, then send the
- * event:
- */
- if (!file || (event->base.file_priv == file)) {
- mdp4_crtc->event = NULL;
+ mdp4_crtc->event = NULL;
+ if (canceled)
+ event->base.destroy(&event->base);
+ else
drm_send_vblank_event(dev, mdp4_crtc->id, event);
- }
}
spin_unlock_irqrestore(&dev->event_lock, flags);
}
@@ -124,15 +115,9 @@ static void crtc_flush(struct drm_crtc *crtc)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
- uint32_t i, flush = 0;
+ uint32_t flush = 0;
- for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
- struct drm_plane *plane = mdp4_crtc->planes[i];
- if (plane) {
- enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
- flush |= pipe2flush(pipe_id);
- }
- }
+ flush |= pipe2flush(mdp4_plane_pipe(mdp4_crtc->plane));
flush |= ovlp2flush(mdp4_crtc->ovlp);
DBG("%s: flush=%08x", mdp4_crtc->name, flush);
@@ -140,29 +125,17 @@ static void crtc_flush(struct drm_crtc *crtc)
mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush);
}
-static void request_pending(struct drm_crtc *crtc, uint32_t pending)
-{
- struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
-
- atomic_or(pending, &mdp4_crtc->pending);
- mdp4_irq_register(get_kms(crtc), &mdp4_crtc->vblank);
-}
-
-static void pageflip_cb(struct msm_fence_cb *cb)
+static void pageflip_worker(struct work_struct *work)
{
struct mdp4_crtc *mdp4_crtc =
- container_of(cb, struct mdp4_crtc, pageflip_cb);
+ container_of(work, struct mdp4_crtc, pageflip_work);
struct drm_crtc *crtc = &mdp4_crtc->base;
- struct drm_framebuffer *fb = crtc->fb;
- if (!fb)
- return;
-
- mdp4_plane_set_scanout(mdp4_crtc->plane, fb);
+ mdp4_plane_set_scanout(mdp4_crtc->plane, crtc->fb);
crtc_flush(crtc);
/* enable vblank to complete flip: */
- request_pending(crtc, PENDING_FLIP);
+ mdp4_irq_register(get_kms(crtc), &mdp4_crtc->vblank);
}
static void unref_fb_worker(struct drm_flip_work *work, void *val)
@@ -232,69 +205,67 @@ static void blend_setup(struct drm_crtc *crtc)
struct mdp4_kms *mdp4_kms = get_kms(crtc);
int i, ovlp = mdp4_crtc->ovlp;
uint32_t mixer_cfg = 0;
- static const enum mdp4_mixer_stage_id stages[] = {
- STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3,
- };
- /* statically (for now) map planes to mixer stage (z-order): */
- static const int idxs[] = {
- [VG1] = 1,
- [VG2] = 2,
- [RGB1] = 0,
- [RGB2] = 0,
- [RGB3] = 0,
- [VG3] = 3,
- [VG4] = 4,
-
- };
- bool alpha[4]= { false, false, false, false };
+
+ /*
+ * This probably would also need to be triggered by any attached
+ * plane when it changes.. for now since we are only using a single
+ * private plane, the configuration is hard-coded:
+ */
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);
- /* TODO single register for all CRTCs, so this won't work properly
- * when multiple CRTCs are active..
- */
- for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
- struct drm_plane *plane = mdp4_crtc->planes[i];
- if (plane) {
- enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
- int idx = idxs[pipe_id];
- if (idx > 0) {
- const struct mdp4_format *format =
- to_mdp4_format(msm_framebuffer_format(plane->fb));
- alpha[idx-1] = format->alpha_enable;
- }
- mixer_cfg |= mixercfg(mdp4_crtc->mixer, pipe_id, stages[idx]);
- }
- }
-
- /* this shouldn't happen.. and seems to cause underflow: */
- WARN_ON(!mixer_cfg);
-
for (i = 0; i < 4; i++) {
- uint32_t op;
-
- if (alpha[i]) {
- op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_PIXEL) |
- MDP4_OVLP_STAGE_OP_BG_ALPHA(FG_PIXEL) |
- MDP4_OVLP_STAGE_OP_BG_INV_ALPHA;
- } else {
- op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
- MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST);
- }
-
- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0xff);
- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0x00);
- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i), op);
- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 1);
+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0);
+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0);
+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i),
+ MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
+ MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST));
+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
}
+ /* TODO single register for all CRTCs, so this won't work properly
+ * when multiple CRTCs are active..
+ */
+ switch (mdp4_plane_pipe(mdp4_crtc->plane)) {
+ case VG1:
+ mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(STAGE_BASE) |
+ COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
+ break;
+ case VG2:
+ mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(STAGE_BASE) |
+ COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
+ break;
+ case RGB1:
+ mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(STAGE_BASE) |
+ COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
+ break;
+ case RGB2:
+ mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(STAGE_BASE) |
+ COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
+ break;
+ case RGB3:
+ mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(STAGE_BASE) |
+ COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
+ break;
+ case VG3:
+ mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(STAGE_BASE) |
+ COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
+ break;
+ case VG4:
+ mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(STAGE_BASE) |
+ COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
+ break;
+ default:
+ WARN_ON("invalid pipe");
+ break;
+ }
mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
}
@@ -406,7 +377,6 @@ static int mdp4_crtc_page_flip(struct drm_crtc *crtc,
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct drm_gem_object *obj;
- unsigned long flags;
if (mdp4_crtc->event) {
dev_err(dev->dev, "already pending flip!\n");
@@ -415,13 +385,11 @@ static int mdp4_crtc_page_flip(struct drm_crtc *crtc,
obj = msm_framebuffer_bo(new_fb, 0);
- spin_lock_irqsave(&dev->event_lock, flags);
mdp4_crtc->event = event;
- spin_unlock_irqrestore(&dev->event_lock, flags);
-
update_fb(crtc, true, new_fb);
- return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb);
+ return msm_gem_queue_inactive_work(obj,
+ &mdp4_crtc->pageflip_work);
}
static int mdp4_crtc_set_property(struct drm_crtc *crtc,
@@ -530,8 +498,6 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
drm_gem_object_unreference_unlocked(old_bo);
}
- request_pending(crtc, PENDING_CURSOR);
-
return 0;
fail:
@@ -576,21 +542,13 @@ static void mdp4_crtc_vblank_irq(struct mdp4_irq *irq, uint32_t irqstatus)
struct mdp4_crtc *mdp4_crtc = container_of(irq, struct mdp4_crtc, vblank);
struct drm_crtc *crtc = &mdp4_crtc->base;
struct msm_drm_private *priv = crtc->dev->dev_private;
- unsigned pending;
+ update_cursor(crtc);
+ complete_flip(crtc, false);
mdp4_irq_unregister(get_kms(crtc), &mdp4_crtc->vblank);
- pending = atomic_xchg(&mdp4_crtc->pending, 0);
-
- if (pending & PENDING_FLIP) {
- complete_flip(crtc, NULL);
- drm_flip_work_commit(&mdp4_crtc->unref_fb_work, priv->wq);
- }
-
- if (pending & PENDING_CURSOR) {
- update_cursor(crtc);
- drm_flip_work_commit(&mdp4_crtc->unref_cursor_work, priv->wq);
- }
+ drm_flip_work_commit(&mdp4_crtc->unref_fb_work, priv->wq);
+ drm_flip_work_commit(&mdp4_crtc->unref_cursor_work, priv->wq);
}
static void mdp4_crtc_err_irq(struct mdp4_irq *irq, uint32_t irqstatus)
@@ -607,10 +565,9 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc)
return mdp4_crtc->vblank.irqmask;
}
-void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file)
+void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc)
{
- DBG("cancel: %p", file);
- complete_flip(crtc, file);
+ complete_flip(crtc, true);
}
/* set dma config, ie. the format the encoder wants. */
@@ -665,32 +622,6 @@ void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf)
mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);
}
-static void set_attach(struct drm_crtc *crtc, enum mdp4_pipe pipe_id,
- struct drm_plane *plane)
-{
- struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
-
- BUG_ON(pipe_id >= ARRAY_SIZE(mdp4_crtc->planes));
-
- if (mdp4_crtc->planes[pipe_id] == plane)
- return;
-
- mdp4_crtc->planes[pipe_id] = plane;
- blend_setup(crtc);
- if (mdp4_crtc->enabled && (plane != mdp4_crtc->plane))
- crtc_flush(crtc);
-}
-
-void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane)
-{
- set_attach(crtc, mdp4_plane_pipe(plane), plane);
-}
-
-void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane)
-{
- set_attach(crtc, mdp4_plane_pipe(plane), NULL);
-}
-
static const char *dma_names[] = {
"DMA_P", "DMA_S", "DMA_E",
};
@@ -713,6 +644,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
crtc = &mdp4_crtc->base;
mdp4_crtc->plane = plane;
+ mdp4_crtc->plane->crtc = crtc;
mdp4_crtc->ovlp = ovlp_id;
mdp4_crtc->dma = dma_id;
@@ -736,7 +668,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
ret = drm_flip_work_init(&mdp4_crtc->unref_cursor_work, 64,
"unref cursor", unref_cursor_worker);
- INIT_FENCE_CB(&mdp4_crtc->pageflip_cb, pageflip_cb);
+ INIT_WORK(&mdp4_crtc->pageflip_work, pageflip_worker);
drm_crtc_init(dev, crtc, &mdp4_crtc_funcs);
drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_format.c b/drivers/gpu/drm/msm/mdp4/mdp4_format.c
index 17330b0..7b645f2 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_format.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_format.c
@@ -44,22 +44,6 @@ static const struct mdp4_format formats[] = {
FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3),
};
-uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats,
- uint32_t max_formats)
-{
- uint32_t i;
- for (i = 0; i < ARRAY_SIZE(formats); i++) {
- const struct mdp4_format *f = &formats[i];
-
- if (i == max_formats)
- break;
-
- pixel_formats[i] = f->base.pixel_format;
- }
-
- return i;
-}
-
const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format)
{
int i;
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp4/mdp4_kms.c
index 8972ac3..bc7fd11 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_kms.c
@@ -135,7 +135,7 @@ static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file)
unsigned i;
for (i = 0; i < priv->num_crtcs; i++)
- mdp4_crtc_cancel_pending_flip(priv->crtcs[i], file);
+ mdp4_crtc_cancel_pending_flip(priv->crtcs[i]);
}
static void mdp4_destroy(struct msm_kms *kms)
@@ -196,23 +196,6 @@ static int modeset_init(struct mdp4_kms *mdp4_kms)
* for more than just RGB1->DMA_E->DTV->HDMI
*/
- /* construct non-private planes: */
- plane = mdp4_plane_init(dev, VG1, false);
- if (IS_ERR(plane)) {
- dev_err(dev->dev, "failed to construct plane for VG1\n");
- ret = PTR_ERR(plane);
- goto fail;
- }
- priv->planes[priv->num_planes++] = plane;
-
- plane = mdp4_plane_init(dev, VG2, false);
- if (IS_ERR(plane)) {
- dev_err(dev->dev, "failed to construct plane for VG2\n");
- ret = PTR_ERR(plane);
- goto fail;
- }
- priv->planes[priv->num_planes++] = plane;
-
/* the CRTCs get constructed with a private plane: */
plane = mdp4_plane_init(dev, RGB1, true);
if (IS_ERR(plane)) {
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp4/mdp4_kms.h
index eb015c8..1e83554 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_kms.h
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_kms.h
@@ -75,8 +75,8 @@ struct mdp4_platform_config {
struct mdp4_format {
struct msm_format base;
- enum mdp4_bpc bpc_r, bpc_g, bpc_b;
- enum mdp4_bpc_alpha bpc_a;
+ enum mpd4_bpc bpc_r, bpc_g, bpc_b;
+ enum mpd4_bpc_alpha bpc_a;
uint8_t unpack[4];
bool alpha_enable, unpack_tight;
uint8_t cpp, unpack_count;
@@ -93,7 +93,7 @@ static inline u32 mdp4_read(struct mdp4_kms *mdp4_kms, u32 reg)
return msm_readl(mdp4_kms->mmio + reg);
}
-static inline uint32_t pipe2flush(enum mdp4_pipe pipe)
+static inline uint32_t pipe2flush(enum mpd4_pipe pipe)
{
switch (pipe) {
case VG1: return MDP4_OVERLAY_FLUSH_VG1;
@@ -133,48 +133,6 @@ static inline uint32_t dma2err(enum mdp4_dma dma)
}
}
-static inline uint32_t mixercfg(int mixer, enum mdp4_pipe pipe,
- enum mdp4_mixer_stage_id stage)
-{
- uint32_t mixer_cfg = 0;
-
- switch (pipe) {
- case VG1:
- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) |
- COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
- break;
- case VG2:
- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) |
- COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
- break;
- case RGB1:
- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) |
- COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
- break;
- case RGB2:
- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) |
- COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
- break;
- case RGB3:
- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) |
- COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
- break;
- case VG3:
- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) |
- COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
- break;
- case VG4:
- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) |
- COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
- break;
- default:
- WARN_ON("invalid pipe");
- break;
- }
-
- return mixer_cfg;
-}
-
int mdp4_disable(struct mdp4_kms *mdp4_kms);
int mdp4_enable(struct mdp4_kms *mdp4_kms);
@@ -188,8 +146,6 @@ void mdp4_irq_unregister(struct mdp4_kms *mdp4_kms, struct mdp4_irq *irq);
int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
-uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *formats,
- uint32_t max_formats);
const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format);
void mdp4_plane_install_properties(struct drm_plane *plane,
@@ -202,16 +158,14 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h);
-enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane);
+enum mpd4_pipe mdp4_plane_pipe(struct drm_plane *plane);
struct drm_plane *mdp4_plane_init(struct drm_device *dev,
- enum mdp4_pipe pipe_id, bool private_plane);
+ enum mpd4_pipe pipe_id, bool private_plane);
uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
-void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
+void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc);
void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf);
-void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane);
-void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane);
struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
struct drm_plane *plane, int id, int ovlp_id,
enum mdp4_dma dma_id);
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp4/mdp4_plane.c
index 0f0af24..3468229 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_plane.c
@@ -22,7 +22,7 @@ struct mdp4_plane {
struct drm_plane base;
const char *name;
- enum mdp4_pipe pipe;
+ enum mpd4_pipe pipe;
uint32_t nformats;
uint32_t formats[32];
@@ -61,9 +61,7 @@ static int mdp4_plane_update(struct drm_plane *plane,
static int mdp4_plane_disable(struct drm_plane *plane)
{
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
- DBG("%s: disable", mdp4_plane->name);
- if (plane->crtc)
- mdp4_crtc_detach(plane->crtc, plane);
+ DBG("%s: TODO", mdp4_plane->name); // XXX
return 0;
}
@@ -103,7 +101,7 @@ void mdp4_plane_set_scanout(struct drm_plane *plane,
{
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
struct mdp4_kms *mdp4_kms = get_kms(plane);
- enum mdp4_pipe pipe = mdp4_plane->pipe;
+ enum mpd4_pipe pipe = mdp4_plane->pipe;
uint32_t iova;
mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe),
@@ -131,7 +129,7 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
{
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
struct mdp4_kms *mdp4_kms = get_kms(plane);
- enum mdp4_pipe pipe = mdp4_plane->pipe;
+ enum mpd4_pipe pipe = mdp4_plane->pipe;
const struct mdp4_format *format;
uint32_t op_mode = 0;
uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
@@ -143,10 +141,6 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
src_w = src_w >> 16;
src_h = src_h >> 16;
- DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", mdp4_plane->name,
- fb->base.id, src_x, src_y, src_w, src_h,
- crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
-
if (src_w != crtc_w) {
op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
/* TODO calc phasex_step */
@@ -197,8 +191,7 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
- /* TODO detach from old crtc (if we had more than one) */
- mdp4_crtc_attach(crtc, plane);
+ plane->crtc = crtc;
return 0;
}
@@ -209,7 +202,7 @@ static const char *pipe_names[] = {
"VG3", "VG4",
};
-enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane)
+enum mpd4_pipe mdp4_plane_pipe(struct drm_plane *plane)
{
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
return mdp4_plane->pipe;
@@ -217,8 +210,9 @@ enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane)
/* initialize plane */
struct drm_plane *mdp4_plane_init(struct drm_device *dev,
- enum mdp4_pipe pipe_id, bool private_plane)
+ enum mpd4_pipe pipe_id, bool private_plane)
{
+ struct msm_drm_private *priv = dev->dev_private;
struct drm_plane *plane = NULL;
struct mdp4_plane *mdp4_plane;
int ret;
@@ -234,12 +228,8 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
mdp4_plane->pipe = pipe_id;
mdp4_plane->name = pipe_names[pipe_id];
- mdp4_plane->nformats = mdp4_get_formats(pipe_id, mdp4_plane->formats,
- ARRAY_SIZE(mdp4_plane->formats));
-
- drm_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
- mdp4_plane->formats, mdp4_plane->nformats,
- private_plane);
+ drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &mdp4_plane_funcs,
+ mdp4_plane->formats, mdp4_plane->nformats, private_plane);
mdp4_plane_install_properties(plane, &plane->base);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 8653769..b3a2f16 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -187,7 +187,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
init_waitqueue_head(&priv->fence_event);
INIT_LIST_HEAD(&priv->inactive_list);
- INIT_LIST_HEAD(&priv->fence_cbs);
drm_mode_config_init(dev);
@@ -540,36 +539,15 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
return ret;
}
-/* called from workqueue */
+/* call under struct_mutex */
void msm_update_fence(struct drm_device *dev, uint32_t fence)
{
struct msm_drm_private *priv = dev->dev_private;
- mutex_lock(&dev->struct_mutex);
- priv->completed_fence = max(fence, priv->completed_fence);
-
- while (!list_empty(&priv->fence_cbs)) {
- struct msm_fence_cb *cb;
-
- cb = list_first_entry(&priv->fence_cbs,
- struct msm_fence_cb, work.entry);
-
- if (cb->fence > priv->completed_fence)
- break;
-
- list_del_init(&cb->work.entry);
- queue_work(priv->wq, &cb->work);
+ if (fence > priv->completed_fence) {
+ priv->completed_fence = fence;
+ wake_up_all(&priv->fence_event);
}
-
- mutex_unlock(&dev->struct_mutex);
-
- wake_up_all(&priv->fence_event);
-}
-
-void __msm_fence_worker(struct work_struct *work)
-{
- struct msm_fence_cb *cb = container_of(work, struct msm_fence_cb, work);
- cb->func(cb);
}
/*
@@ -672,13 +650,13 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
}
static const struct drm_ioctl_desc msm_ioctls[] = {
- DRM_IOCTL_DEF_DRV(MSM_GET_PARAM, msm_ioctl_get_param, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(MSM_GEM_INFO, msm_ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_FINI, msm_ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT, msm_ioctl_gem_submit, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE, msm_ioctl_wait_fence, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(MSM_GET_PARAM, msm_ioctl_get_param, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(MSM_GEM_INFO, msm_ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_FINI, msm_ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT, msm_ioctl_gem_submit, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE, msm_ioctl_wait_fence, DRM_UNLOCKED|DRM_AUTH),
};
static const struct vm_operations_struct vm_ops = {
@@ -702,11 +680,7 @@ static const struct file_operations fops = {
};
static struct drm_driver msm_driver = {
- .driver_features = DRIVER_HAVE_IRQ |
- DRIVER_GEM |
- DRIVER_PRIME |
- DRIVER_RENDER |
- DRIVER_MODESET,
+ .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
.load = msm_load,
.unload = msm_unload,
.open = msm_open,
@@ -724,16 +698,6 @@ static struct drm_driver msm_driver = {
.dumb_create = msm_gem_dumb_create,
.dumb_map_offset = msm_gem_dumb_map_offset,
.dumb_destroy = drm_gem_dumb_destroy,
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
- .gem_prime_export = drm_gem_prime_export,
- .gem_prime_import = drm_gem_prime_import,
- .gem_prime_pin = msm_gem_prime_pin,
- .gem_prime_unpin = msm_gem_prime_unpin,
- .gem_prime_get_sg_table = msm_gem_prime_get_sg_table,
- .gem_prime_import_sg_table = msm_gem_prime_import_sg_table,
- .gem_prime_vmap = msm_gem_prime_vmap,
- .gem_prime_vunmap = msm_gem_prime_vunmap,
#ifdef CONFIG_DEBUG_FS
.debugfs_init = msm_debugfs_init,
.debugfs_cleanup = msm_debugfs_cleanup,
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index d39f086..df8f1d0 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -73,16 +73,10 @@ struct msm_drm_private {
struct workqueue_struct *wq;
- /* callbacks deferred until bo is inactive: */
- struct list_head fence_cbs;
-
/* registered IOMMU domains: */
unsigned int num_iommus;
struct iommu_domain *iommus[NUM_DOMAINS];
- unsigned int num_planes;
- struct drm_plane *planes[8];
-
unsigned int num_crtcs;
struct drm_crtc *crtcs[8];
@@ -100,20 +94,6 @@ struct msm_format {
uint32_t pixel_format;
};
-/* callback from wq once fence has passed: */
-struct msm_fence_cb {
- struct work_struct work;
- uint32_t fence;
- void (*func)(struct msm_fence_cb *cb);
-};
-
-void __msm_fence_worker(struct work_struct *work);
-
-#define INIT_FENCE_CB(_cb, _func) do { \
- INIT_WORK(&(_cb)->work, __msm_fence_worker); \
- (_cb)->func = _func; \
- } while (0)
-
/* As there are different display controller blocks depending on the
* snapdragon version, the kms support is split out and the appropriate
* implementation is loaded at runtime. The kms module is responsible
@@ -161,24 +141,17 @@ uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
uint32_t *iova);
int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova);
-struct page **msm_gem_get_pages(struct drm_gem_object *obj);
-void msm_gem_put_pages(struct drm_gem_object *obj);
void msm_gem_put_iova(struct drm_gem_object *obj, int id);
int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
+int msm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+ uint32_t handle);
int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
-struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj);
-void *msm_gem_prime_vmap(struct drm_gem_object *obj);
-void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
-struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
- size_t size, struct sg_table *sg);
-int msm_gem_prime_pin(struct drm_gem_object *obj);
-void msm_gem_prime_unpin(struct drm_gem_object *obj);
void *msm_gem_vaddr_locked(struct drm_gem_object *obj);
void *msm_gem_vaddr(struct drm_gem_object *obj);
-int msm_gem_queue_inactive_cb(struct drm_gem_object *obj,
- struct msm_fence_cb *cb);
+int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
+ struct work_struct *work);
void msm_gem_move_to_active(struct drm_gem_object *obj,
struct msm_gpu *gpu, bool write, uint32_t fence);
void msm_gem_move_to_inactive(struct drm_gem_object *obj);
@@ -190,8 +163,6 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
uint32_t size, uint32_t flags, uint32_t *handle);
struct drm_gem_object *msm_gem_new(struct drm_device *dev,
uint32_t size, uint32_t flags);
-struct drm_gem_object *msm_gem_import(struct drm_device *dev,
- uint32_t size, struct sg_table *sgt);
struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index e587d25..2bae46c 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -17,7 +17,6 @@
#include <linux/spinlock.h>
#include <linux/shmem_fs.h>
-#include <linux/dma-buf.h>
#include "msm_drv.h"
#include "msm_gem.h"
@@ -78,21 +77,6 @@ static void put_pages(struct drm_gem_object *obj)
}
}
-struct page **msm_gem_get_pages(struct drm_gem_object *obj)
-{
- struct drm_device *dev = obj->dev;
- struct page **p;
- mutex_lock(&dev->struct_mutex);
- p = get_pages(obj);
- mutex_unlock(&dev->struct_mutex);
- return p;
-}
-
-void msm_gem_put_pages(struct drm_gem_object *obj)
-{
- /* when we start tracking the pin count, then do something here */
-}
-
int msm_gem_mmap_obj(struct drm_gem_object *obj,
struct vm_area_struct *vma)
{
@@ -178,11 +162,6 @@ out:
case 0:
case -ERESTARTSYS:
case -EINTR:
- case -EBUSY:
- /*
- * EBUSY is ok: this just means that another thread
- * already did the job.
- */
return VM_FAULT_NOPAGE;
case -ENOMEM:
return VM_FAULT_OOM;
@@ -314,17 +293,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova)
{
- struct msm_gem_object *msm_obj = to_msm_bo(obj);
int ret;
-
- /* this is safe right now because we don't unmap until the
- * bo is deleted:
- */
- if (msm_obj->domain[id].iova) {
- *iova = msm_obj->domain[id].iova;
- return 0;
- }
-
mutex_lock(&obj->dev->struct_mutex);
ret = msm_gem_get_iova_locked(obj, id, iova);
mutex_unlock(&obj->dev->struct_mutex);
@@ -394,11 +363,8 @@ void *msm_gem_vaddr(struct drm_gem_object *obj)
return ret;
}
-/* setup callback for when bo is no longer busy..
- * TODO probably want to differentiate read vs write..
- */
-int msm_gem_queue_inactive_cb(struct drm_gem_object *obj,
- struct msm_fence_cb *cb)
+int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
+ struct work_struct *work)
{
struct drm_device *dev = obj->dev;
struct msm_drm_private *priv = dev->dev_private;
@@ -406,13 +372,12 @@ int msm_gem_queue_inactive_cb(struct drm_gem_object *obj,
int ret = 0;
mutex_lock(&dev->struct_mutex);
- if (!list_empty(&cb->work.entry)) {
+ if (!list_empty(&work->entry)) {
ret = -EINVAL;
} else if (is_active(msm_obj)) {
- cb->fence = max(msm_obj->read_fence, msm_obj->write_fence);
- list_add_tail(&cb->work.entry, &priv->fence_cbs);
+ list_add_tail(&work->entry, &msm_obj->inactive_work);
} else {
- queue_work(priv->wq, &cb->work);
+ queue_work(priv->wq, work);
}
mutex_unlock(&dev->struct_mutex);
@@ -445,6 +410,16 @@ void msm_gem_move_to_inactive(struct drm_gem_object *obj)
msm_obj->write_fence = 0;
list_del_init(&msm_obj->mm_list);
list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
+
+ while (!list_empty(&msm_obj->inactive_work)) {
+ struct work_struct *work;
+
+ work = list_first_entry(&msm_obj->inactive_work,
+ struct work_struct, entry);
+
+ list_del_init(&work->entry);
+ queue_work(priv->wq, work);
+ }
}
int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
@@ -535,21 +510,10 @@ void msm_gem_free_object(struct drm_gem_object *obj)
drm_gem_free_mmap_offset(obj);
- if (obj->import_attach) {
- if (msm_obj->vaddr)
- dma_buf_vunmap(obj->import_attach->dmabuf, msm_obj->vaddr);
+ if (msm_obj->vaddr)
+ vunmap(msm_obj->vaddr);
- /* Don't drop the pages for imported dmabuf, as they are not
- * ours, just free the array we allocated:
- */
- if (msm_obj->pages)
- drm_free_large(msm_obj->pages);
-
- } else {
- if (msm_obj->vaddr)
- vunmap(msm_obj->vaddr);
- put_pages(obj);
- }
+ put_pages(obj);
if (msm_obj->resv == &msm_obj->_resv)
reservation_object_fini(msm_obj->resv);
@@ -585,12 +549,17 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
return ret;
}
-static int msm_gem_new_impl(struct drm_device *dev,
- uint32_t size, uint32_t flags,
- struct drm_gem_object **obj)
+struct drm_gem_object *msm_gem_new(struct drm_device *dev,
+ uint32_t size, uint32_t flags)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_gem_object *msm_obj;
+ struct drm_gem_object *obj = NULL;
+ int ret;
+
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ size = PAGE_ALIGN(size);
switch (flags & MSM_BO_CACHE_MASK) {
case MSM_BO_UNCACHED:
@@ -600,81 +569,30 @@ static int msm_gem_new_impl(struct drm_device *dev,
default:
dev_err(dev->dev, "invalid cache flag: %x\n",
(flags & MSM_BO_CACHE_MASK));
- return -EINVAL;
+ ret = -EINVAL;
+ goto fail;
}
msm_obj = kzalloc(sizeof(*msm_obj), GFP_KERNEL);
- if (!msm_obj)
- return -ENOMEM;
-
- msm_obj->flags = flags;
-
- msm_obj->resv = &msm_obj->_resv;
- reservation_object_init(msm_obj->resv);
-
- INIT_LIST_HEAD(&msm_obj->submit_entry);
- list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
-
- *obj = &msm_obj->base;
-
- return 0;
-}
-
-struct drm_gem_object *msm_gem_new(struct drm_device *dev,
- uint32_t size, uint32_t flags)
-{
- struct drm_gem_object *obj;
- int ret;
-
- WARN_ON(!mutex_is_locked(&dev->struct_mutex));
-
- size = PAGE_ALIGN(size);
-
- ret = msm_gem_new_impl(dev, size, flags, &obj);
- if (ret)
- goto fail;
-
- ret = drm_gem_object_init(dev, obj, size);
- if (ret)
+ if (!msm_obj) {
+ ret = -ENOMEM;
goto fail;
+ }
- return obj;
-
-fail:
- if (obj)
- drm_gem_object_unreference_unlocked(obj);
-
- return ERR_PTR(ret);
-}
-
-struct drm_gem_object *msm_gem_import(struct drm_device *dev,
- uint32_t size, struct sg_table *sgt)
-{
- struct msm_gem_object *msm_obj;
- struct drm_gem_object *obj;
- int ret, npages;
-
- size = PAGE_ALIGN(size);
+ obj = &msm_obj->base;
- ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj);
+ ret = drm_gem_object_init(dev, obj, size);
if (ret)
goto fail;
- drm_gem_private_object_init(dev, obj, size);
-
- npages = size / PAGE_SIZE;
+ msm_obj->flags = flags;
- msm_obj = to_msm_bo(obj);
- msm_obj->sgt = sgt;
- msm_obj->pages = drm_malloc_ab(npages, sizeof(struct page *));
- if (!msm_obj->pages) {
- ret = -ENOMEM;
- goto fail;
- }
+ msm_obj->resv = &msm_obj->_resv;
+ reservation_object_init(msm_obj->resv);
- ret = drm_prime_sg_to_page_addr_arrays(sgt, msm_obj->pages, NULL, npages);
- if (ret)
- goto fail;
+ INIT_LIST_HEAD(&msm_obj->submit_entry);
+ INIT_LIST_HEAD(&msm_obj->inactive_work);
+ list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
return obj;
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index f4f23a5..0676f32 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -45,6 +45,9 @@ struct msm_gem_object {
*/
struct list_head submit_entry;
+ /* work defered until bo is inactive: */
+ struct list_head inactive_work;
+
struct page **pages;
struct sg_table *sgt;
void *vaddr;
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c
deleted file mode 100644
index d48f9fc..0000000
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2013 Red Hat
- * Author: Rob Clark <robdclark@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "msm_drv.h"
-#include "msm_gem.h"
-
-
-struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
-{
- struct msm_gem_object *msm_obj = to_msm_bo(obj);
- BUG_ON(!msm_obj->sgt); /* should have already pinned! */
- return msm_obj->sgt;
-}
-
-void *msm_gem_prime_vmap(struct drm_gem_object *obj)
-{
- return msm_gem_vaddr(obj);
-}
-
-void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
-{
- /* TODO msm_gem_vunmap() */
-}
-
-struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
- size_t size, struct sg_table *sg)
-{
- return msm_gem_import(dev, size, sg);
-}
-
-int msm_gem_prime_pin(struct drm_gem_object *obj)
-{
- if (!obj->import_attach)
- msm_gem_get_pages(obj);
- return 0;
-}
-
-void msm_gem_prime_unpin(struct drm_gem_object *obj)
-{
- if (!obj->import_attach)
- msm_gem_put_pages(obj);
-}
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 4583d61..3bab937 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -268,8 +268,6 @@ static void retire_worker(struct work_struct *work)
struct drm_device *dev = gpu->dev;
uint32_t fence = gpu->funcs->last_fence(gpu);
- msm_update_fence(gpu->dev, fence);
-
mutex_lock(&dev->struct_mutex);
while (!list_empty(&gpu->active_list)) {
@@ -289,6 +287,8 @@ static void retire_worker(struct work_struct *work)
}
}
+ msm_update_fence(gpu->dev, fence);
+
mutex_unlock(&dev->struct_mutex);
}
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 7cf787d..ff80f12 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -3,7 +3,6 @@ config DRM_NOUVEAU
depends on DRM && PCI
select FW_LOADER
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_TTM
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index b3fa1ba..d939a1d 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -28,9 +28,7 @@ nouveau-y += core/subdev/bar/nv50.o
nouveau-y += core/subdev/bar/nvc0.o
nouveau-y += core/subdev/bios/base.o
nouveau-y += core/subdev/bios/bit.o
-nouveau-y += core/subdev/bios/boost.o
nouveau-y += core/subdev/bios/conn.o
-nouveau-y += core/subdev/bios/cstep.o
nouveau-y += core/subdev/bios/dcb.o
nouveau-y += core/subdev/bios/disp.o
nouveau-y += core/subdev/bios/dp.o
@@ -41,27 +39,17 @@ nouveau-y += core/subdev/bios/init.o
nouveau-y += core/subdev/bios/mxm.o
nouveau-y += core/subdev/bios/perf.o
nouveau-y += core/subdev/bios/pll.o
-nouveau-y += core/subdev/bios/rammap.o
-nouveau-y += core/subdev/bios/timing.o
nouveau-y += core/subdev/bios/therm.o
-nouveau-y += core/subdev/bios/vmap.o
-nouveau-y += core/subdev/bios/volt.o
nouveau-y += core/subdev/bios/xpio.o
-nouveau-y += core/subdev/bus/hwsq.o
nouveau-y += core/subdev/bus/nv04.o
nouveau-y += core/subdev/bus/nv31.o
nouveau-y += core/subdev/bus/nv50.o
-nouveau-y += core/subdev/bus/nv94.o
nouveau-y += core/subdev/bus/nvc0.o
-nouveau-y += core/subdev/clock/base.o
nouveau-y += core/subdev/clock/nv04.o
nouveau-y += core/subdev/clock/nv40.o
nouveau-y += core/subdev/clock/nv50.o
-nouveau-y += core/subdev/clock/nv84.o
nouveau-y += core/subdev/clock/nva3.o
-nouveau-y += core/subdev/clock/nvaa.o
nouveau-y += core/subdev/clock/nvc0.o
-nouveau-y += core/subdev/clock/nve0.o
nouveau-y += core/subdev/clock/pllnv04.o
nouveau-y += core/subdev/clock/pllnva3.o
nouveau-y += core/subdev/devinit/base.o
@@ -90,12 +78,7 @@ nouveau-y += core/subdev/fb/nv47.o
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/nv84.o
-nouveau-y += core/subdev/fb/nva3.o
-nouveau-y += core/subdev/fb/nvaa.o
-nouveau-y += core/subdev/fb/nvaf.o
nouveau-y += core/subdev/fb/nvc0.o
-nouveau-y += core/subdev/fb/nve0.o
nouveau-y += core/subdev/fb/ramnv04.o
nouveau-y += core/subdev/fb/ramnv10.o
nouveau-y += core/subdev/fb/ramnv1a.o
@@ -106,12 +89,7 @@ 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/ramnva3.o
-nouveau-y += core/subdev/fb/ramnvaa.o
nouveau-y += core/subdev/fb/ramnvc0.o
-nouveau-y += core/subdev/fb/ramnve0.o
-nouveau-y += core/subdev/fb/sddr3.o
-nouveau-y += core/subdev/fb/gddr5.o
nouveau-y += core/subdev/gpio/base.o
nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv50.o
@@ -135,22 +113,13 @@ nouveau-y += core/subdev/instmem/nv50.o
nouveau-y += core/subdev/ltcg/nvc0.o
nouveau-y += core/subdev/mc/base.o
nouveau-y += core/subdev/mc/nv04.o
-nouveau-y += core/subdev/mc/nv40.o
nouveau-y += core/subdev/mc/nv44.o
nouveau-y += core/subdev/mc/nv50.o
-nouveau-y += core/subdev/mc/nv94.o
nouveau-y += core/subdev/mc/nv98.o
nouveau-y += core/subdev/mc/nvc0.o
-nouveau-y += core/subdev/mc/nvc3.o
nouveau-y += core/subdev/mxm/base.o
nouveau-y += core/subdev/mxm/mxms.o
nouveau-y += core/subdev/mxm/nv50.o
-nouveau-y += core/subdev/pwr/base.o
-nouveau-y += core/subdev/pwr/memx.o
-nouveau-y += core/subdev/pwr/nva3.o
-nouveau-y += core/subdev/pwr/nvc0.o
-nouveau-y += core/subdev/pwr/nvd0.o
-nouveau-y += core/subdev/pwr/nv108.o
nouveau-y += core/subdev/therm/base.o
nouveau-y += core/subdev/therm/fan.o
nouveau-y += core/subdev/therm/fannil.o
@@ -171,9 +140,6 @@ nouveau-y += core/subdev/vm/nv41.o
nouveau-y += core/subdev/vm/nv44.o
nouveau-y += core/subdev/vm/nv50.o
nouveau-y += core/subdev/vm/nvc0.o
-nouveau-y += core/subdev/volt/base.o
-nouveau-y += core/subdev/volt/gpio.o
-nouveau-y += core/subdev/volt/nv40.o
nouveau-y += core/engine/falcon.o
nouveau-y += core/engine/xtensa.o
@@ -192,7 +158,6 @@ nouveau-y += core/engine/copy/nve0.o
nouveau-y += core/engine/crypt/nv84.o
nouveau-y += core/engine/crypt/nv98.o
nouveau-y += core/engine/device/base.o
-nouveau-y += core/engine/device/ctrl.o
nouveau-y += core/engine/device/nv04.o
nouveau-y += core/engine/device/nv10.o
nouveau-y += core/engine/device/nv20.o
@@ -262,18 +227,8 @@ nouveau-y += core/engine/graph/nve4.o
nouveau-y += core/engine/graph/nvf0.o
nouveau-y += core/engine/mpeg/nv31.o
nouveau-y += core/engine/mpeg/nv40.o
-nouveau-y += core/engine/mpeg/nv44.o
nouveau-y += core/engine/mpeg/nv50.o
nouveau-y += core/engine/mpeg/nv84.o
-nouveau-y += core/engine/perfmon/base.o
-nouveau-y += core/engine/perfmon/daemon.o
-nouveau-y += core/engine/perfmon/nv40.o
-nouveau-y += core/engine/perfmon/nv50.o
-nouveau-y += core/engine/perfmon/nv84.o
-nouveau-y += core/engine/perfmon/nva3.o
-nouveau-y += core/engine/perfmon/nvc0.o
-nouveau-y += core/engine/perfmon/nve0.o
-nouveau-y += core/engine/perfmon/nvf0.o
nouveau-y += core/engine/ppp/nv98.o
nouveau-y += core/engine/ppp/nvc0.o
nouveau-y += core/engine/software/nv04.o
@@ -305,7 +260,9 @@ include $(src)/dispnv04/Makefile
nouveau-y += nv50_display.o
# drm/pm
-nouveau-y += nouveau_hwmon.o nouveau_sysfs.o
+nouveau-y += nouveau_pm.o nouveau_volt.o nouveau_perf.o
+nouveau-y += nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o
+nouveau-y += nouveau_mem.o
# other random bits
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c
index 3f3c765..7eb81c1 100644
--- a/drivers/gpu/drm/nouveau/core/core/event.c
+++ b/drivers/gpu/drm/nouveau/core/core/event.c
@@ -23,114 +23,62 @@
#include <core/os.h>
#include <core/event.h>
-void
-nouveau_event_put(struct nouveau_eventh *handler)
+static void
+nouveau_event_put_locked(struct nouveau_event *event, int index,
+ struct nouveau_eventh *handler)
{
- struct nouveau_event *event = handler->event;
- unsigned long flags;
- if (__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags)) {
- spin_lock_irqsave(&event->refs_lock, flags);
- if (!--event->index[handler->index].refs) {
- if (event->disable)
- event->disable(event, handler->index);
- }
- spin_unlock_irqrestore(&event->refs_lock, flags);
+ if (!--event->index[index].refs) {
+ if (event->disable)
+ event->disable(event, index);
}
+ list_del(&handler->head);
}
void
-nouveau_event_get(struct nouveau_eventh *handler)
+nouveau_event_put(struct nouveau_event *event, int index,
+ struct nouveau_eventh *handler)
{
- struct nouveau_event *event = handler->event;
unsigned long flags;
- if (!__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags)) {
- spin_lock_irqsave(&event->refs_lock, flags);
- if (!event->index[handler->index].refs++) {
- if (event->enable)
- event->enable(event, handler->index);
- }
- spin_unlock_irqrestore(&event->refs_lock, flags);
- }
-}
-static void
-nouveau_event_fini(struct nouveau_eventh *handler)
-{
- struct nouveau_event *event = handler->event;
- unsigned long flags;
- nouveau_event_put(handler);
- spin_lock_irqsave(&event->list_lock, flags);
- list_del(&handler->head);
- spin_unlock_irqrestore(&event->list_lock, flags);
+ spin_lock_irqsave(&event->lock, flags);
+ if (index < event->index_nr)
+ nouveau_event_put_locked(event, index, handler);
+ spin_unlock_irqrestore(&event->lock, flags);
}
-static int
-nouveau_event_init(struct nouveau_event *event, int index,
- int (*func)(void *, int), void *priv,
- struct nouveau_eventh *handler)
+void
+nouveau_event_get(struct nouveau_event *event, int index,
+ struct nouveau_eventh *handler)
{
unsigned long flags;
- if (index >= event->index_nr)
- return -EINVAL;
-
- handler->event = event;
- handler->flags = 0;
- handler->index = index;
- handler->func = func;
- handler->priv = priv;
-
- spin_lock_irqsave(&event->list_lock, flags);
- list_add_tail(&handler->head, &event->index[index].list);
- spin_unlock_irqrestore(&event->list_lock, flags);
- return 0;
-}
-
-int
-nouveau_event_new(struct nouveau_event *event, int index,
- int (*func)(void *, int), void *priv,
- struct nouveau_eventh **phandler)
-{
- struct nouveau_eventh *handler;
- int ret = -ENOMEM;
-
- handler = *phandler = kmalloc(sizeof(*handler), GFP_KERNEL);
- if (handler) {
- ret = nouveau_event_init(event, index, func, priv, handler);
- if (ret)
- kfree(handler);
- }
-
- return ret;
-}
-
-void
-nouveau_event_ref(struct nouveau_eventh *handler, struct nouveau_eventh **ref)
-{
- BUG_ON(handler != NULL);
- if (*ref) {
- nouveau_event_fini(*ref);
- kfree(*ref);
+ spin_lock_irqsave(&event->lock, flags);
+ if (index < event->index_nr) {
+ list_add(&handler->head, &event->index[index].list);
+ if (!event->index[index].refs++) {
+ if (event->enable)
+ event->enable(event, index);
+ }
}
- *ref = handler;
+ spin_unlock_irqrestore(&event->lock, flags);
}
void
nouveau_event_trigger(struct nouveau_event *event, int index)
{
- struct nouveau_eventh *handler;
+ struct nouveau_eventh *handler, *temp;
unsigned long flags;
- if (WARN_ON(index >= event->index_nr))
+ if (index >= event->index_nr)
return;
- spin_lock_irqsave(&event->list_lock, flags);
- list_for_each_entry(handler, &event->index[index].list, head) {
- if (test_bit(NVKM_EVENT_ENABLE, &handler->flags) &&
- handler->func(handler->priv, index) == NVKM_EVENT_DROP)
- nouveau_event_put(handler);
+ spin_lock_irqsave(&event->lock, flags);
+ list_for_each_entry_safe(handler, temp, &event->index[index].list, head) {
+ if (handler->func(handler, index) == NVKM_EVENT_DROP) {
+ nouveau_event_put_locked(event, index, handler);
+ }
}
- spin_unlock_irqrestore(&event->list_lock, flags);
+ spin_unlock_irqrestore(&event->lock, flags);
}
void
@@ -154,8 +102,7 @@ nouveau_event_create(int index_nr, struct nouveau_event **pevent)
if (!event)
return -ENOMEM;
- spin_lock_init(&event->list_lock);
- spin_lock_init(&event->refs_lock);
+ spin_lock_init(&event->lock);
for (i = 0; i < index_nr; i++)
INIT_LIST_HEAD(&event->index[i].list);
event->index_nr = index_nr;
diff --git a/drivers/gpu/drm/nouveau/core/core/option.c b/drivers/gpu/drm/nouveau/core/core/option.c
index 9f6fcc5..62a432e 100644
--- a/drivers/gpu/drm/nouveau/core/core/option.c
+++ b/drivers/gpu/drm/nouveau/core/core/option.c
@@ -25,6 +25,15 @@
#include <core/option.h>
#include <core/debug.h>
+/* compares unterminated string 'str' with zero-terminated string 'cmp' */
+static inline int
+strncasecmpz(const char *str, const char *cmp, size_t len)
+{
+ if (strlen(cmp) != len)
+ return len;
+ return strncasecmp(str, cmp, len);
+}
+
const char *
nouveau_stropt(const char *optstr, const char *opt, int *arglen)
{
@@ -96,7 +105,7 @@ nouveau_dbgopt(const char *optstr, const char *sub)
else if (!strncasecmpz(optstr, "warn", len))
level = NV_DBG_WARN;
else if (!strncasecmpz(optstr, "info", len))
- level = NV_DBG_INFO_NORMAL;
+ level = NV_DBG_INFO;
else if (!strncasecmpz(optstr, "debug", len))
level = NV_DBG_DEBUG;
else if (!strncasecmpz(optstr, "trace", len))
diff --git a/drivers/gpu/drm/nouveau/core/core/printk.c b/drivers/gpu/drm/nouveau/core/core/printk.c
index 03e0060..52fb2aa 100644
--- a/drivers/gpu/drm/nouveau/core/core/printk.c
+++ b/drivers/gpu/drm/nouveau/core/core/printk.c
@@ -27,38 +27,16 @@
#include <core/subdev.h>
#include <core/printk.h>
-int nv_info_debug_level = NV_DBG_INFO_NORMAL;
+int nv_printk_suspend_level = NV_DBG_DEBUG;
void
-nv_printk_(struct nouveau_object *object, int level, const char *fmt, ...)
+nv_printk_(struct nouveau_object *object, const char *pfx, int level,
+ const char *fmt, ...)
{
static const char name[] = { '!', 'E', 'W', ' ', 'D', 'T', 'P', 'S' };
- const char *pfx;
char mfmt[256];
va_list args;
- switch (level) {
- case NV_DBG_FATAL:
- pfx = KERN_CRIT;
- break;
- case NV_DBG_ERROR:
- pfx = KERN_ERR;
- break;
- case NV_DBG_WARN:
- pfx = KERN_WARNING;
- break;
- case NV_DBG_INFO_NORMAL:
- pfx = KERN_INFO;
- break;
- case NV_DBG_DEBUG:
- case NV_DBG_PARANOIA:
- case NV_DBG_TRACE:
- case NV_DBG_SPAM:
- default:
- pfx = KERN_DEBUG;
- break;
- }
-
if (object && !nv_iclass(object, NV_CLIENT_CLASS)) {
struct nouveau_object *device = object;
struct nouveau_object *subdev = object;
@@ -96,3 +74,20 @@ nv_printk_(struct nouveau_object *object, int level, const char *fmt, ...)
vprintk(mfmt, args);
va_end(args);
}
+
+#define CONV_LEVEL(x) case NV_DBG_##x: return NV_PRINTK_##x
+
+const char *nv_printk_level_to_pfx(int level)
+{
+ switch (level) {
+ CONV_LEVEL(FATAL);
+ CONV_LEVEL(ERROR);
+ CONV_LEVEL(WARN);
+ CONV_LEVEL(INFO);
+ CONV_LEVEL(DEBUG);
+ CONV_LEVEL(PARANOIA);
+ CONV_LEVEL(TRACE);
+ CONV_LEVEL(SPAM);
+ }
+ return NV_PRINTK_DEBUG;
+}
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index 9135b25a..4c72571 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -29,7 +29,7 @@
#include <core/class.h>
-#include "priv.h"
+#include <engine/device.h>
static DEFINE_MUTEX(nv_devices_mutex);
static LIST_HEAD(nv_devices);
@@ -75,9 +75,7 @@ static const u64 disable_map[] = {
[NVDEV_SUBDEV_BAR] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_VOLT] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE,
- [NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE,
[NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE,
- [NVDEV_ENGINE_PERFMON] = NV_DEVICE_DISABLE_CORE,
[NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO,
[NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO,
[NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH,
@@ -89,7 +87,7 @@ static const u64 disable_map[] = {
[NVDEV_ENGINE_PPP] = NV_DEVICE_DISABLE_PPP,
[NVDEV_ENGINE_COPY0] = NV_DEVICE_DISABLE_COPY0,
[NVDEV_ENGINE_COPY1] = NV_DEVICE_DISABLE_COPY1,
- [NVDEV_ENGINE_VIC] = NV_DEVICE_DISABLE_VIC,
+ [NVDEV_ENGINE_UNK1C1] = NV_DEVICE_DISABLE_UNK1C1,
[NVDEV_ENGINE_VENC] = NV_DEVICE_DISABLE_VENC,
[NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP,
[NVDEV_SUBDEV_NR] = 0,
@@ -121,12 +119,10 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
return -ENODEV;
}
- ret = nouveau_parent_create(parent, nv_object(device), oclass, 0,
- nouveau_control_oclass,
+ ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_FIFO) |
- (1ULL << NVDEV_ENGINE_DISP) |
- (1ULL << NVDEV_ENGINE_PERFMON), &devobj);
+ (1ULL << NVDEV_ENGINE_DISP), &devobj);
*pobject = nv_object(devobj);
if (ret)
return ret;
@@ -162,29 +158,22 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
iounmap(map);
/* determine chipset and derive architecture from it */
- if ((boot0 & 0x1f000000) > 0) {
- device->chipset = (boot0 & 0x1ff00000) >> 20;
- switch (device->chipset & 0x1f0) {
- case 0x010: {
- if (0x461 & (1 << (device->chipset & 0xf)))
- device->card_type = NV_10;
- else
- device->card_type = NV_11;
- break;
- }
- case 0x020: device->card_type = NV_20; break;
- case 0x030: device->card_type = NV_30; break;
- case 0x040:
- case 0x060: device->card_type = NV_40; break;
- case 0x050:
- case 0x080:
- case 0x090:
- case 0x0a0: device->card_type = NV_50; break;
- case 0x0c0: device->card_type = NV_C0; break;
- case 0x0d0: device->card_type = NV_D0; break;
- case 0x0e0:
- case 0x0f0:
- case 0x100: device->card_type = NV_E0; break;
+ if ((boot0 & 0x0f000000) > 0) {
+ device->chipset = (boot0 & 0xff00000) >> 20;
+ switch (device->chipset & 0xf0) {
+ case 0x10: device->card_type = NV_10; break;
+ case 0x20: device->card_type = NV_20; break;
+ case 0x30: device->card_type = NV_30; break;
+ case 0x40:
+ case 0x60: device->card_type = NV_40; break;
+ case 0x50:
+ case 0x80:
+ case 0x90:
+ case 0xa0: device->card_type = NV_50; break;
+ case 0xc0: device->card_type = NV_C0; break;
+ case 0xd0: device->card_type = NV_D0; break;
+ case 0xe0:
+ case 0xf0: device->card_type = NV_E0; break;
default:
break;
}
@@ -199,8 +188,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
switch (device->card_type) {
case NV_04: ret = nv04_identify(device); break;
- case NV_10:
- case NV_11: ret = nv10_identify(device); break;
+ case NV_10: ret = nv10_identify(device); break;
case NV_20: ret = nv20_identify(device); break;
case NV_30: ret = nv30_identify(device); break;
case NV_40: ret = nv40_identify(device); break;
@@ -224,7 +212,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
nv_info(device, "Family : NV%02X\n", device->card_type);
/* determine frequency of timing crystal */
- if ( device->card_type <= NV_10 || device->chipset < 0x17 ||
+ if ( device->chipset < 0x17 ||
(device->chipset >= 0x20 && device->chipset < 0x25))
strap &= 0x00000040;
else
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c
deleted file mode 100644
index 4b69bf5..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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 <bskeggs@redhat.com>
- */
-
-#include <core/object.h>
-#include <core/class.h>
-
-#include <subdev/clock.h>
-
-#include "priv.h"
-
-static int
-nouveau_control_mthd_pstate_info(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
-{
- struct nouveau_clock *clk = nouveau_clock(object);
- struct nv_control_pstate_info *args = data;
-
- if (size < sizeof(*args))
- return -EINVAL;
-
- if (clk) {
- args->count = clk->state_nr;
- args->ustate = clk->ustate;
- args->pstate = clk->pstate;
- } else {
- args->count = 0;
- args->ustate = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE;
- args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN;
- }
-
- return 0;
-}
-
-static int
-nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
-{
- struct nouveau_clock *clk = nouveau_clock(object);
- struct nv_control_pstate_attr *args = data;
- struct nouveau_clocks *domain;
- struct nouveau_pstate *pstate;
- struct nouveau_cstate *cstate;
- int i = 0, j = -1;
- u32 lo, hi;
-
- if ((size < sizeof(*args)) || !clk ||
- (args->state >= 0 && args->state >= clk->state_nr))
- return -EINVAL;
- domain = clk->domains;
-
- while (domain->name != nv_clk_src_max) {
- if (domain->mname && ++j == args->index)
- break;
- domain++;
- }
-
- if (domain->name == nv_clk_src_max)
- return -EINVAL;
-
- if (args->state != NV_CONTROL_PSTATE_ATTR_STATE_CURRENT) {
- list_for_each_entry(pstate, &clk->states, head) {
- if (i++ == args->state)
- break;
- }
-
- lo = pstate->base.domain[domain->name];
- hi = lo;
- list_for_each_entry(cstate, &pstate->list, head) {
- lo = min(lo, cstate->domain[domain->name]);
- hi = max(hi, cstate->domain[domain->name]);
- }
-
- args->state = pstate->pstate;
- } else {
- lo = max(clk->read(clk, domain->name), 0);
- hi = lo;
- }
-
- snprintf(args->name, sizeof(args->name), "%s", domain->mname);
- snprintf(args->unit, sizeof(args->unit), "MHz");
- args->min = lo / domain->mdiv;
- args->max = hi / domain->mdiv;
-
- args->index = 0;
- while ((++domain)->name != nv_clk_src_max) {
- if (domain->mname) {
- args->index = ++j;
- break;
- }
- }
-
- return 0;
-}
-
-static int
-nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
-{
- struct nouveau_clock *clk = nouveau_clock(object);
- struct nv_control_pstate_user *args = data;
-
- if (size < sizeof(*args) || !clk)
- return -EINVAL;
-
- return nouveau_clock_ustate(clk, args->state);
-}
-
-struct nouveau_oclass
-nouveau_control_oclass[] = {
- { .handle = NV_CONTROL_CLASS,
- .ofuncs = &nouveau_object_ofuncs,
- .omthds = (struct nouveau_omthds[]) {
- { NV_CONTROL_PSTATE_INFO,
- NV_CONTROL_PSTATE_INFO, nouveau_control_mthd_pstate_info },
- { NV_CONTROL_PSTATE_ATTR,
- NV_CONTROL_PSTATE_ATTR, nouveau_control_mthd_pstate_attr },
- { NV_CONTROL_PSTATE_USER,
- NV_CONTROL_PSTATE_USER, nouveau_control_mthd_pstate_user },
- {},
- },
- },
- {}
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c
index dbd2dde..a0284cf 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c
@@ -50,15 +50,15 @@ nv04_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv04_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv04_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv04_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -68,15 +68,15 @@ nv04_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv05_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv04_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv04_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c
index 6e03dd6..1b7809a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c
@@ -52,10 +52,10 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
@@ -69,15 +69,15 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -88,15 +88,15 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -107,15 +107,15 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv1a_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -126,15 +126,15 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -145,15 +145,15 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -164,15 +164,15 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv1a_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -183,15 +183,15 @@ nv10_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c
index dcde53b..12a4005 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c
@@ -53,15 +53,15 @@ nv20_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv20_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv20_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -72,15 +72,15 @@ nv20_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -91,15 +91,15 @@ nv20_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -110,15 +110,15 @@ nv20_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv2a_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c
index 7b8662e..cef0f1e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c
@@ -53,15 +53,15 @@ nv30_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -72,15 +72,15 @@ nv30_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv35_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv35_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
break;
@@ -91,15 +91,15 @@ nv30_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
@@ -111,15 +111,15 @@ nv30_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv36_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv36_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
@@ -131,15 +131,15 @@ nv30_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv34_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c
index c8c41e9..1719cb0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c
@@ -35,7 +35,6 @@
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
-#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
@@ -44,7 +43,6 @@
#include <engine/graph.h>
#include <engine/mpeg.h>
#include <engine/disp.h>
-#include <engine/perfmon.h>
int
nv40_identify(struct nouveau_device *device)
@@ -58,20 +56,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x41:
device->cname = "NV41";
@@ -81,20 +77,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x42:
device->cname = "NV42";
@@ -104,20 +98,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x43:
device->cname = "NV43";
@@ -127,20 +119,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x45:
device->cname = "NV45";
@@ -150,20 +140,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x47:
device->cname = "G70";
@@ -173,20 +161,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv47_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv47_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x49:
device->cname = "G71";
@@ -196,20 +182,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv49_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4b:
device->cname = "G73";
@@ -219,20 +203,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv49_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x44:
device->cname = "NV44";
@@ -242,20 +224,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv44_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x46:
device->cname = "G72";
@@ -265,20 +245,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4a:
device->cname = "NV44A";
@@ -288,20 +266,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv44_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4c:
device->cname = "C61";
@@ -311,20 +287,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4e:
device->cname = "C51";
@@ -334,20 +308,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv4e_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x63:
device->cname = "C73";
@@ -357,20 +329,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x67:
device->cname = "C67";
@@ -380,20 +350,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x68:
device->cname = "C68";
@@ -403,20 +371,18 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
default:
nv_fatal(device, "unknown Curie chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
index db3fc7b..ffc18b8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
@@ -36,8 +36,6 @@
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/bar.h>
-#include <subdev/pwr.h>
-#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
@@ -51,7 +49,6 @@
#include <engine/ppp.h>
#include <engine/copy.h>
#include <engine/disp.h>
-#include <engine/perfmon.h>
int
nv50_identify(struct nouveau_device *device)
@@ -62,277 +59,257 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv50_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv50_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv50_perfmon_oclass;
break;
case 0x84:
device->cname = "G84";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x86:
device->cname = "G86";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x92:
device->cname = "G92";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x94:
device->cname = "G94";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x96:
device->cname = "G96";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x98:
device->cname = "G98";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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 ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_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;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xa0:
device->cname = "G200";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva0_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xaa:
device->cname = "MCP77/MCP78";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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 ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_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;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xac:
device->cname = "MCP79/MCP7A";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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 ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_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;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xa3:
device->cname = "GT215";
@@ -343,18 +320,16 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
@@ -362,7 +337,6 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
case 0xa5:
device->cname = "GT216";
@@ -373,25 +347,22 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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 ] = &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;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
case 0xa8:
device->cname = "GT218";
@@ -402,25 +373,22 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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 ] = &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;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
case 0xaf:
device->cname = "MCP89";
@@ -431,25 +399,22 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvaf_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
+ 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 ] = &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;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
default:
nv_fatal(device, "unknown Tesla chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
index 8d06eef..418f51f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
@@ -38,8 +38,6 @@
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/bar.h>
-#include <subdev/pwr.h>
-#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
@@ -51,7 +49,6 @@
#include <engine/ppp.h>
#include <engine/copy.h>
#include <engine/disp.h>
-#include <engine/perfmon.h>
int
nvc0_identify(struct nouveau_device *device)
@@ -66,20 +63,18 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_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_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc0_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
@@ -87,7 +82,6 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc4:
device->cname = "GF104";
@@ -98,20 +92,18 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_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_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
@@ -119,7 +111,6 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc3:
device->cname = "GF106";
@@ -130,27 +121,24 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xce:
device->cname = "GF114";
@@ -161,20 +149,18 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
@@ -182,7 +168,6 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xcf:
device->cname = "GF116";
@@ -193,20 +178,18 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
@@ -214,7 +197,6 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc1:
device->cname = "GF108";
@@ -225,27 +207,24 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc1_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc8:
device->cname = "GF110";
@@ -256,20 +235,18 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_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_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc8_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
@@ -277,7 +254,6 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xd9:
device->cname = "GF119";
@@ -288,27 +264,24 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvd9_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xd7:
device->cname = "GF117";
@@ -319,25 +292,24 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvd7_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
default:
nv_fatal(device, "unknown Fermi chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
index 3900104..7aca187 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
@@ -38,8 +38,6 @@
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/bar.h>
-#include <subdev/pwr.h>
-#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
@@ -51,7 +49,6 @@
#include <engine/bsp.h>
#include <engine/vp.h>
#include <engine/ppp.h>
-#include <engine/perfmon.h>
int
nve0_identify(struct nouveau_device *device)
@@ -62,24 +59,22 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
+ 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] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
@@ -88,31 +83,28 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
break;
case 0xe7:
device->cname = "GK107";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
+ 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] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
@@ -121,31 +113,28 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
break;
case 0xe6:
device->cname = "GK106";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
+ 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] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
@@ -154,31 +143,28 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
break;
case 0xf0:
device->cname = "GK110";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
+ 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] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_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;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nvf0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
@@ -189,43 +175,6 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
#endif
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
- break;
- case 0x108:
- device->cname = "GK208";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = &nv108_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
-#if 0
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass;
-#endif
- device->oclass[NVDEV_ENGINE_DISP ] = &nvf0_disp_oclass;
-#if 0
- 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;
-#endif
break;
default:
nv_fatal(device, "unknown Kepler chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/priv.h b/drivers/gpu/drm/nouveau/core/engine/device/priv.h
deleted file mode 100644
index 035fd5b..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/device/priv.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __NVKM_DEVICE_PRIV_H__
-#define __NVKM_DEVICE_PRIV_H__
-
-#include <engine/device.h>
-
-extern struct nouveau_oclass nouveau_control_oclass[];
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
index 1bd4c63..054d9cf 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
@@ -70,10 +70,17 @@ dp_set_link_config(struct dp_state *dp)
};
u32 lnkcmp;
u8 sink[2];
- int ret;
DBG("%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
+ /* set desired link configuration on the sink */
+ sink[0] = dp->link_bw / 27000;
+ sink[1] = dp->link_nr;
+ if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
+ sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
+
+ nv_wraux(dp->aux, DPCD_LC00, sink, 2);
+
/* set desired link configuration on the source */
if ((lnkcmp = dp->info.lnkcmp)) {
if (dp->version < 0x30) {
@@ -89,22 +96,10 @@ dp_set_link_config(struct dp_state *dp)
nvbios_exec(&init);
}
- ret = dp->func->lnk_ctl(dp->disp, dp->outp, dp->head,
- dp->link_nr, dp->link_bw / 27000,
- dp->dpcd[DPCD_RC02] &
- DPCD_RC02_ENHANCED_FRAME_CAP);
- if (ret) {
- ERR("lnk_ctl failed with %d\n", ret);
- return ret;
- }
-
- /* set desired link configuration on the sink */
- sink[0] = dp->link_bw / 27000;
- sink[1] = dp->link_nr;
- if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
- sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
-
- return nv_wraux(dp->aux, DPCD_LC00, sink, 2);
+ return dp->func->lnk_ctl(dp->disp, dp->outp, dp->head,
+ dp->link_nr, dp->link_bw / 27000,
+ dp->dpcd[DPCD_RC02] &
+ DPCD_RC02_ENHANCED_FRAME_CAP);
}
static void
@@ -299,17 +294,8 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
ret = nv_rdaux(dp->aux, 0x00000, dp->dpcd, sizeof(dp->dpcd));
if (ret) {
- /* it's possible the display has been unplugged before we
- * get here. we still need to execute the full set of
- * vbios scripts, and program the OR at a high enough
- * frequency to satisfy the target mode. failure to do
- * so results at best in an UPDATE hanging, and at worst
- * with PDISP running away to join the circus.
- */
- dp->dpcd[1] = link_bw[0] / 27000;
- dp->dpcd[2] = 4;
- dp->dpcd[3] = 0x00;
ERR("failed to read DPCD\n");
+ return ret;
}
/* adjust required bandwidth for 8B/10B coding overhead */
@@ -322,7 +308,7 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
while (*link_bw > (dp->dpcd[1] * 27000))
link_bw++;
- while ((ret = -EIO) && link_bw[0]) {
+ while (link_bw[0]) {
/* find minimum required lane count at this link rate */
dp->link_nr = dp->dpcd[2] & DPCD_RC02_MAX_LANE_COUNT;
while ((dp->link_nr >> 1) * link_bw[0] > datarate)
@@ -342,10 +328,8 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
!dp_link_train_eq(dp))
break;
} else
- if (ret) {
- /* dp_set_link_config() handled training, or
- * we failed to communicate with the sink.
- */
+ if (ret >= 1) {
+ /* dp_set_link_config() handled training */
break;
}
@@ -355,10 +339,8 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
/* finish link training */
dp_set_training_pattern(dp, 0);
- if (ret < 0)
- ERR("link training failed\n");
/* execute post-train script from vbios */
dp_link_train_fini(dp);
- return (ret < 0) ? false : true;
+ return true;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
index a0bc8a8..05e903f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
@@ -59,7 +59,6 @@ nv04_disp_intr(struct nouveau_subdev *subdev)
struct nv04_disp_priv *priv = (void *)subdev;
u32 crtc0 = nv_rd32(priv, 0x600100);
u32 crtc1 = nv_rd32(priv, 0x602100);
- u32 pvideo;
if (crtc0 & 0x00000001) {
nouveau_event_trigger(priv->base.vblank, 0);
@@ -70,14 +69,6 @@ nv04_disp_intr(struct nouveau_subdev *subdev)
nouveau_event_trigger(priv->base.vblank, 1);
nv_wr32(priv, 0x602100, 0x00000001);
}
-
- if (nv_device(priv)->chipset >= 0x10 &&
- nv_device(priv)->chipset <= 0x40) {
- pvideo = nv_rd32(priv, 0x8100);
- if (pvideo & ~0x11)
- nv_info(priv, "PVIDEO intr: %08x\n", pvideo);
- nv_wr32(priv, 0x8100, pvideo);
- }
}
static int
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index 378a015..52dd7a1 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -541,15 +541,6 @@ nvd0_disp_base_init(struct nouveau_object *object)
nv_wr32(priv, 0x6100a0, 0x00000000);
nv_wr32(priv, 0x6100b0, 0x00000307);
- /* disable underflow reporting, preventing an intermittent issue
- * on some nve4 boards where the production vbios left this
- * setting enabled by default.
- *
- * ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt
- */
- for (i = 0; i < priv->head.nr; i++)
- nv_mask(priv, 0x616308 + (i * 0x800), 0x00000111, 0x00000010);
-
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
index eea3ef5..7ec4ee83 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
@@ -97,9 +97,8 @@ nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
{
struct nouveau_bios *bios = nouveau_bios(disp);
struct nv50_disp_priv *priv = (void *)disp;
- const u32 shift = nv94_sor_dp_lane_map(priv, lane);
const u32 loff = nv94_sor_loff(outp);
- u32 addr, data[3];
+ u32 addr, shift = nv94_sor_dp_lane_map(priv, lane);
u8 ver, hdr, cnt, len;
struct nvbios_dpout info;
struct nvbios_dpcfg ocfg;
@@ -114,12 +113,9 @@ nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
if (!addr)
return -EINVAL;
- data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift);
- data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift);
- data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00);
- nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift));
- nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift));
- nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8));
+ nv_mask(priv, 0x61c118 + loff, 0x000000ff << shift, ocfg.drv << shift);
+ nv_mask(priv, 0x61c120 + loff, 0x000000ff << shift, ocfg.pre << shift);
+ nv_mask(priv, 0x61c130 + loff, 0x0000ff00, ocfg.unk << 8);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
index d2df572..9e1d435 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
@@ -93,9 +93,8 @@ nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
{
struct nouveau_bios *bios = nouveau_bios(disp);
struct nv50_disp_priv *priv = (void *)disp;
- const u32 shift = nvd0_sor_dp_lane_map(priv, lane);
const u32 loff = nvd0_sor_loff(outp);
- u32 addr, data[3];
+ u32 addr, shift = nvd0_sor_dp_lane_map(priv, lane);
u8 ver, hdr, cnt, len;
struct nvbios_dpout info;
struct nvbios_dpcfg ocfg;
@@ -110,12 +109,9 @@ nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
if (!addr)
return -EINVAL;
- data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift);
- data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift);
- data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00);
- nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift));
- nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift));
- nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8));
+ nv_mask(priv, 0x61c118 + loff, 0x000000ff << shift, ocfg.drv << shift);
+ nv_mask(priv, 0x61c120 + loff, 0x000000ff << shift, ocfg.pre << shift);
+ nv_mask(priv, 0x61c130 + loff, 0x0000ff00, ocfg.unk << 8);
nv_mask(priv, 0x61c13c + loff, 0x00000000, 0x00000000);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
index 54f26cc..f877bd5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
@@ -632,8 +632,8 @@ nv04_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv04_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv04_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0x04),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
index 571a22a..2c927c1 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
@@ -159,8 +159,8 @@ nv10_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv10_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv10_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0x10),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv10_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c
index f257602..a9cb51d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c
@@ -196,8 +196,8 @@ nv17_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv17_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv17_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0x17),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv17_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
index 343487e..5c7433d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
@@ -337,8 +337,8 @@ nv40_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv40_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv40_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0x40),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv40_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
index e6352bd..7e5dff5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
@@ -33,7 +33,6 @@
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include "nv04.h"
#include "nv50.h"
/*******************************************************************************
@@ -461,8 +460,6 @@ nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv50_fifo_cclass;
nv_engine(priv)->sclass = nv50_fifo_sclass;
- priv->base.pause = nv04_fifo_pause;
- priv->base.start = nv04_fifo_start;
return 0;
}
@@ -505,8 +502,8 @@ nv50_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv50_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv50_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0x50),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
index fe0f41e..91a87cd 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
@@ -35,7 +35,6 @@
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include "nv04.h"
#include "nv50.h"
/*******************************************************************************
@@ -145,7 +144,7 @@ nv84_fifo_object_attach(struct nouveau_object *parent,
case NVDEV_ENGINE_COPY0 : context |= 0x00300000; break;
case NVDEV_ENGINE_VP : context |= 0x00400000; break;
case NVDEV_ENGINE_CRYPT :
- case NVDEV_ENGINE_VIC : context |= 0x00500000; break;
+ case NVDEV_ENGINE_UNK1C1: context |= 0x00500000; break;
case NVDEV_ENGINE_BSP : context |= 0x00600000; break;
default:
return -EINVAL;
@@ -181,7 +180,7 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
(1ULL << NVDEV_ENGINE_BSP) |
(1ULL << NVDEV_ENGINE_PPP) |
(1ULL << NVDEV_ENGINE_COPY0) |
- (1ULL << NVDEV_ENGINE_VIC), &chan);
+ (1ULL << NVDEV_ENGINE_UNK1C1), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -244,7 +243,7 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
(1ULL << NVDEV_ENGINE_BSP) |
(1ULL << NVDEV_ENGINE_PPP) |
(1ULL << NVDEV_ENGINE_COPY0) |
- (1ULL << NVDEV_ENGINE_VIC), &chan);
+ (1ULL << NVDEV_ENGINE_UNK1C1), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -433,13 +432,11 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv84_fifo_cclass;
nv_engine(priv)->sclass = nv84_fifo_sclass;
- priv->base.pause = nv04_fifo_pause;
- priv->base.start = nv04_fifo_start;
return 0;
}
-struct nouveau_oclass *
-nv84_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv84_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
index 9ac94d4..ce92f28 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
@@ -494,6 +494,13 @@ nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit)
u32 mthd = (addr & 0x00003ffc);
u32 show = stat;
+ if (stat & 0x00200000) {
+ if (mthd == 0x0054) {
+ if (!nvc0_fifo_swmthd(priv, chid, 0x0500, 0x00000000))
+ show &= ~0x00200000;
+ }
+ }
+
if (stat & 0x00800000) {
if (!nvc0_fifo_swmthd(priv, chid, mthd, data))
show &= ~0x00800000;
@@ -713,8 +720,8 @@ nvc0_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nvc0_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nvc0_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index 04f4129..8e8121a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -481,6 +481,13 @@ nve0_fifo_isr_subfifo_intr(struct nve0_fifo_priv *priv, int unit)
u32 mthd = (addr & 0x00003ffc);
u32 show = stat;
+ if (stat & 0x00200000) {
+ if (mthd == 0x0054) {
+ if (!nve0_fifo_swmthd(priv, chid, 0x0500, 0x00000000))
+ show &= ~0x00200000;
+ }
+ }
+
if (stat & 0x00800000) {
if (!nve0_fifo_swmthd(priv, chid, mthd, data))
show &= ~0x00800000;
@@ -668,8 +675,8 @@ nve0_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nve0_fifo_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nve0_fifo_oclass = {
.handle = NV_ENGINE(FIFO, 0xe0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_fifo_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
index fe67415..64dca26 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
@@ -1039,7 +1039,7 @@ nvc0_grctx_generate_r406800(struct nvc0_graph_priv *priv)
} while (!tpcnr[gpc]);
tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
- tpc_set |= 1ULL << ((gpc * 8) + tpc);
+ tpc_set |= 1 << ((gpc * 8) + tpc);
}
nv_wr32(priv, 0x406800 + (i * 0x20), lower_32_bits(tpc_set));
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c
index 71b4283..e5be3ee 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c
@@ -587,7 +587,6 @@ nvc1_grctx_init_unk58xx[] = {
{ 0x405870, 4, 0x04, 0x00000001 },
{ 0x405a00, 2, 0x04, 0x00000000 },
{ 0x405a18, 1, 0x04, 0x00000000 },
- {}
};
static struct nvc0_graph_init
@@ -599,7 +598,6 @@ nvc1_grctx_init_rop[] = {
{ 0x408904, 1, 0x04, 0x62000001 },
{ 0x408908, 1, 0x04, 0x00c80929 },
{ 0x408980, 1, 0x04, 0x0000011d },
- {}
};
static struct nvc0_graph_init
@@ -673,7 +671,6 @@ nvc1_grctx_init_gpc_0[] = {
{ 0x419000, 1, 0x04, 0x00000780 },
{ 0x419004, 2, 0x04, 0x00000000 },
{ 0x419014, 1, 0x04, 0x00000004 },
- {}
};
static struct nvc0_graph_init
@@ -720,7 +717,6 @@ nvc1_grctx_init_tpc[] = {
{ 0x419e98, 1, 0x04, 0x00000000 },
{ 0x419ee0, 1, 0x04, 0x00011110 },
{ 0x419f30, 11, 0x04, 0x00000000 },
- {}
};
void
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c
index c4740d5..438e784 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c
@@ -258,7 +258,6 @@ nvd7_grctx_init_hub[] = {
nvc0_grctx_init_unk78xx,
nvc0_grctx_init_unk80xx,
nvd9_grctx_init_rop,
- NULL
};
struct nvc0_graph_init *
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c
index a1102cb..818a475 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c
@@ -466,7 +466,6 @@ nvd9_grctx_init_hub[] = {
nvc0_grctx_init_unk78xx,
nvc0_grctx_init_unk80xx,
nvd9_grctx_init_rop,
- NULL
};
struct nvc0_graph_init *
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
index 4532f7e..23c143a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
@@ -945,8 +945,7 @@ nv10_graph_load_context(struct nv10_graph_chan *chan, int chid)
for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
nv_wr32(priv, nv10_graph_ctx_regs[i], chan->nv10[i]);
- if (nv_device(priv)->card_type >= NV_11 &&
- nv_device(priv)->chipset >= 0x17) {
+ if (nv_device(priv)->chipset >= 0x17) {
for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
nv_wr32(priv, nv17_graph_ctx_regs[i], chan->nv17[i]);
}
@@ -971,8 +970,7 @@ nv10_graph_unload_context(struct nv10_graph_chan *chan)
for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
chan->nv10[i] = nv_rd32(priv, nv10_graph_ctx_regs[i]);
- if (nv_device(priv)->card_type >= NV_11 &&
- nv_device(priv)->chipset >= 0x17) {
+ if (nv_device(priv)->chipset >= 0x17) {
for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
chan->nv17[i] = nv_rd32(priv, nv17_graph_ctx_regs[i]);
}
@@ -1054,8 +1052,7 @@ nv10_graph_context_ctor(struct nouveau_object *parent,
NV_WRITE_CTX(0x00400e14, 0x00001000);
NV_WRITE_CTX(0x00400e30, 0x00080008);
NV_WRITE_CTX(0x00400e34, 0x00080008);
- if (nv_device(priv)->card_type >= NV_11 &&
- nv_device(priv)->chipset >= 0x17) {
+ if (nv_device(priv)->chipset >= 0x17) {
/* is it really needed ??? */
NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
nv_rd32(priv, NV10_PGRAPH_DEBUG_4));
@@ -1234,7 +1231,7 @@ nv10_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_engine(priv)->sclass = nv10_graph_sclass;
else
if (nv_device(priv)->chipset < 0x17 ||
- nv_device(priv)->card_type < NV_11)
+ nv_device(priv)->chipset == 0x1a)
nv_engine(priv)->sclass = nv15_graph_sclass;
else
nv_engine(priv)->sclass = nv17_graph_sclass;
@@ -1273,8 +1270,7 @@ nv10_graph_init(struct nouveau_object *object)
nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31));
- if (nv_device(priv)->card_type >= NV_11 &&
- nv_device(priv)->chipset >= 0x17) {
+ if (nv_device(priv)->chipset >= 0x17) {
nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x1f000000);
nv_wr32(priv, 0x400a10, 0x03ff3fb6);
nv_wr32(priv, 0x400838, 0x002f8684);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
index 434bb4b..3f4f35c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -1138,7 +1138,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_subdev(priv)->unit = 0x08001000;
+ nv_subdev(priv)->unit = 0x18001000;
nv_subdev(priv)->intr = nvc0_graph_intr;
priv->base.units = nvc0_graph_units;
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
index 7eb6d94c..c190043 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
@@ -34,7 +34,16 @@
#include <engine/fifo.h>
#include <engine/mpeg.h>
-#include <engine/mpeg/nv31.h>
+#include <engine/graph/nv40.h>
+
+struct nv31_mpeg_priv {
+ struct nouveau_mpeg base;
+ atomic_t refcount;
+};
+
+struct nv31_mpeg_chan {
+ struct nouveau_object base;
+};
/*******************************************************************************
* MPEG object classes
@@ -80,18 +89,18 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
if (mthd == 0x0190) {
/* DMA_CMD */
- nv_mask(priv, 0x00b300, 0x00010000, (dma0 & 0x00030000) ? 0x00010000 : 0);
+ nv_mask(priv, 0x00b300, 0x00030000, (dma0 & 0x00030000));
nv_wr32(priv, 0x00b334, base);
nv_wr32(priv, 0x00b324, size);
} else
if (mthd == 0x01a0) {
/* DMA_DATA */
- nv_mask(priv, 0x00b300, 0x00020000, (dma0 & 0x00030000) ? 0x00020000 : 0);
+ nv_mask(priv, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2);
nv_wr32(priv, 0x00b360, base);
nv_wr32(priv, 0x00b364, size);
} else {
/* DMA_IMAGE, VRAM only */
- if (dma0 & 0x00030000)
+ if (dma0 & 0x000c0000)
return -EINVAL;
nv_wr32(priv, 0x00b370, base);
@@ -101,7 +110,7 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
return 0;
}
-struct nouveau_ofuncs
+static struct nouveau_ofuncs
nv31_mpeg_ofuncs = {
.ctor = nv31_mpeg_object_ctor,
.dtor = _nouveau_gpuobj_dtor,
@@ -137,23 +146,16 @@ nv31_mpeg_context_ctor(struct nouveau_object *parent,
{
struct nv31_mpeg_priv *priv = (void *)engine;
struct nv31_mpeg_chan *chan;
- unsigned long flags;
int ret;
+ if (!atomic_add_unless(&priv->refcount, 1, 1))
+ return -EBUSY;
+
ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- spin_lock_irqsave(&nv_engine(priv)->lock, flags);
- if (priv->chan) {
- spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
- nouveau_object_destroy(&chan->base);
- *pobject = NULL;
- return -EBUSY;
- }
- priv->chan = chan;
- spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
return 0;
}
@@ -162,15 +164,11 @@ nv31_mpeg_context_dtor(struct nouveau_object *object)
{
struct nv31_mpeg_priv *priv = (void *)object->engine;
struct nv31_mpeg_chan *chan = (void *)object;
- unsigned long flags;
-
- spin_lock_irqsave(&nv_engine(priv)->lock, flags);
- priv->chan = NULL;
- spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
+ atomic_dec(&priv->refcount);
nouveau_object_destroy(&chan->base);
}
-struct nouveau_oclass
+static struct nouveau_oclass
nv31_mpeg_cclass = {
.handle = NV_ENGCTX(MPEG, 0x31),
.ofuncs = &(struct nouveau_ofuncs) {
@@ -199,19 +197,21 @@ nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i)
void
nv31_mpeg_intr(struct nouveau_subdev *subdev)
{
- struct nv31_mpeg_priv *priv = (void *)subdev;
struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_handle *handle;
+ struct nouveau_engine *engine = nv_engine(subdev);
struct nouveau_object *engctx;
+ struct nouveau_handle *handle;
+ struct nv31_mpeg_priv *priv = (void *)subdev;
+ u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
u32 stat = nv_rd32(priv, 0x00b100);
u32 type = nv_rd32(priv, 0x00b230);
u32 mthd = nv_rd32(priv, 0x00b234);
u32 data = nv_rd32(priv, 0x00b238);
u32 show = stat;
- unsigned long flags;
+ int chid;
- spin_lock_irqsave(&nv_engine(priv)->lock, flags);
- engctx = nv_object(priv->chan);
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
if (stat & 0x01000000) {
/* happens on initial binding of the object */
@@ -220,7 +220,7 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
show &= ~0x01000000;
}
- if (type == 0x00000010 && engctx) {
+ if (type == 0x00000010) {
handle = nouveau_handle_get_class(engctx, 0x3174);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~0x01000000;
@@ -232,12 +232,13 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, 0x00b230, 0x00000001);
if (show) {
- nv_error(priv, "ch %d [%s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
- pfifo->chid(pfifo, engctx),
- nouveau_client_name(engctx), stat, type, mthd, data);
+ nv_error(priv,
+ "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ chid, inst << 4, nouveau_client_name(engctx), stat,
+ type, mthd, data);
}
- spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
+ nouveau_engctx_put(engctx);
}
static int
@@ -283,7 +284,10 @@ nv31_mpeg_init(struct nouveau_object *object)
/* PMPEG init */
nv_wr32(priv, 0x00b32c, 0x00000000);
nv_wr32(priv, 0x00b314, 0x00000100);
- nv_wr32(priv, 0x00b220, 0x00000031);
+ if (nv_device(priv)->chipset >= 0x40 && nv44_graph_class(priv))
+ nv_wr32(priv, 0x00b220, 0x00000044);
+ else
+ nv_wr32(priv, 0x00b220, 0x00000031);
nv_wr32(priv, 0x00b300, 0x02001ec1);
nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
deleted file mode 100644
index d08629d..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __NV31_MPEG_H__
-#define __NV31_MPEG_H__
-
-#include <engine/mpeg.h>
-
-struct nv31_mpeg_chan {
- struct nouveau_object base;
-};
-
-struct nv31_mpeg_priv {
- struct nouveau_mpeg base;
- struct nv31_mpeg_chan *chan;
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
index d4e7ec0..dd61960 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
@@ -31,63 +31,66 @@
#include <subdev/instmem.h>
#include <engine/mpeg.h>
-#include <engine/mpeg/nv31.h>
+#include <engine/graph/nv40.h>
+
+struct nv40_mpeg_priv {
+ struct nouveau_mpeg base;
+};
+
+struct nv40_mpeg_chan {
+ struct nouveau_mpeg_chan base;
+};
/*******************************************************************************
- * MPEG object classes
+ * PMPEG context
******************************************************************************/
static int
-nv40_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
+nv40_mpeg_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
{
- struct nouveau_instmem *imem = nouveau_instmem(object);
- struct nv31_mpeg_priv *priv = (void *)object->engine;
- u32 inst = *(u32 *)arg << 4;
- u32 dma0 = nv_ro32(imem, inst + 0);
- u32 dma1 = nv_ro32(imem, inst + 4);
- u32 dma2 = nv_ro32(imem, inst + 8);
- u32 base = (dma2 & 0xfffff000) | (dma0 >> 20);
- u32 size = dma1 + 1;
-
- /* only allow linear DMA objects */
- if (!(dma0 & 0x00002000))
- return -EINVAL;
-
- if (mthd == 0x0190) {
- /* DMA_CMD */
- nv_mask(priv, 0x00b300, 0x00030000, (dma0 & 0x00030000));
- nv_wr32(priv, 0x00b334, base);
- nv_wr32(priv, 0x00b324, size);
- } else
- if (mthd == 0x01a0) {
- /* DMA_DATA */
- nv_mask(priv, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2);
- nv_wr32(priv, 0x00b360, base);
- nv_wr32(priv, 0x00b364, size);
- } else {
- /* DMA_IMAGE, VRAM only */
- if (dma0 & 0x00030000)
- return -EINVAL;
-
- nv_wr32(priv, 0x00b370, base);
- nv_wr32(priv, 0x00b374, size);
- }
+ struct nv40_mpeg_chan *chan;
+ int ret;
+ ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL,
+ 264 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_wo32(&chan->base.base, 0x78, 0x02001ec1);
return 0;
}
-static struct nouveau_omthds
-nv40_mpeg_omthds[] = {
- { 0x0190, 0x0190, nv40_mpeg_mthd_dma },
- { 0x01a0, 0x01a0, nv40_mpeg_mthd_dma },
- { 0x01b0, 0x01b0, nv40_mpeg_mthd_dma },
- {}
-};
+static int
+nv40_mpeg_context_fini(struct nouveau_object *object, bool suspend)
+{
-struct nouveau_oclass
-nv40_mpeg_sclass[] = {
- { 0x3174, &nv31_mpeg_ofuncs, nv40_mpeg_omthds },
- {}
+ struct nv40_mpeg_priv *priv = (void *)object->engine;
+ struct nv40_mpeg_chan *chan = (void *)object;
+ u32 inst = 0x80000000 | nv_gpuobj(chan)->addr >> 4;
+
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000000);
+ if (nv_rd32(priv, 0x00b318) == inst)
+ nv_mask(priv, 0x00b318, 0x80000000, 0x00000000);
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv40_mpeg_cclass = {
+ .handle = NV_ENGCTX(MPEG, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_mpeg_context_ctor,
+ .dtor = _nouveau_mpeg_context_dtor,
+ .init = _nouveau_mpeg_context_init,
+ .fini = nv40_mpeg_context_fini,
+ .rd32 = _nouveau_mpeg_context_rd32,
+ .wr32 = _nouveau_mpeg_context_wr32,
+ },
};
/*******************************************************************************
@@ -97,7 +100,7 @@ nv40_mpeg_sclass[] = {
static void
nv40_mpeg_intr(struct nouveau_subdev *subdev)
{
- struct nv31_mpeg_priv *priv = (void *)subdev;
+ struct nv40_mpeg_priv *priv = (void *)subdev;
u32 stat;
if ((stat = nv_rd32(priv, 0x00b100)))
@@ -114,7 +117,7 @@ nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv31_mpeg_priv *priv;
+ struct nv40_mpeg_priv *priv;
int ret;
ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
@@ -124,8 +127,8 @@ nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->unit = 0x00000002;
nv_subdev(priv)->intr = nv40_mpeg_intr;
- nv_engine(priv)->cclass = &nv31_mpeg_cclass;
- nv_engine(priv)->sclass = nv40_mpeg_sclass;
+ nv_engine(priv)->cclass = &nv40_mpeg_cclass;
+ nv_engine(priv)->sclass = nv31_mpeg_sclass;
nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c
deleted file mode 100644
index 3d8c213..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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/os.h>
-#include <core/class.h>
-#include <core/client.h>
-#include <core/engctx.h>
-#include <core/handle.h>
-
-#include <subdev/fb.h>
-#include <subdev/timer.h>
-#include <subdev/instmem.h>
-
-#include <engine/fifo.h>
-#include <engine/mpeg.h>
-
-struct nv44_mpeg_priv {
- struct nouveau_mpeg base;
-};
-
-struct nv44_mpeg_chan {
- struct nouveau_mpeg_chan base;
-};
-
-/*******************************************************************************
- * PMPEG context
- ******************************************************************************/
-
-static int
-nv44_mpeg_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv44_mpeg_chan *chan;
- int ret;
-
- ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL,
- 264 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &chan);
- *pobject = nv_object(chan);
- if (ret)
- return ret;
-
- nv_wo32(&chan->base.base, 0x78, 0x02001ec1);
- return 0;
-}
-
-static int
-nv44_mpeg_context_fini(struct nouveau_object *object, bool suspend)
-{
-
- struct nv44_mpeg_priv *priv = (void *)object->engine;
- struct nv44_mpeg_chan *chan = (void *)object;
- u32 inst = 0x80000000 | nv_gpuobj(chan)->addr >> 4;
-
- nv_mask(priv, 0x00b32c, 0x00000001, 0x00000000);
- if (nv_rd32(priv, 0x00b318) == inst)
- nv_mask(priv, 0x00b318, 0x80000000, 0x00000000);
- nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
- return 0;
-}
-
-static struct nouveau_oclass
-nv44_mpeg_cclass = {
- .handle = NV_ENGCTX(MPEG, 0x44),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv44_mpeg_context_ctor,
- .dtor = _nouveau_mpeg_context_dtor,
- .init = _nouveau_mpeg_context_init,
- .fini = nv44_mpeg_context_fini,
- .rd32 = _nouveau_mpeg_context_rd32,
- .wr32 = _nouveau_mpeg_context_wr32,
- },
-};
-
-/*******************************************************************************
- * PMPEG engine/subdev functions
- ******************************************************************************/
-
-static void
-nv44_mpeg_intr(struct nouveau_subdev *subdev)
-{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nouveau_handle *handle;
- struct nv44_mpeg_priv *priv = (void *)subdev;
- u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
- u32 stat = nv_rd32(priv, 0x00b100);
- u32 type = nv_rd32(priv, 0x00b230);
- u32 mthd = nv_rd32(priv, 0x00b234);
- u32 data = nv_rd32(priv, 0x00b238);
- u32 show = stat;
- int chid;
-
- engctx = nouveau_engctx_get(engine, inst);
- chid = pfifo->chid(pfifo, engctx);
-
- if (stat & 0x01000000) {
- /* happens on initial binding of the object */
- if (type == 0x00000020 && mthd == 0x0000) {
- nv_mask(priv, 0x00b308, 0x00000000, 0x00000000);
- show &= ~0x01000000;
- }
-
- if (type == 0x00000010) {
- handle = nouveau_handle_get_class(engctx, 0x3174);
- if (handle && !nv_call(handle->object, mthd, data))
- show &= ~0x01000000;
- nouveau_handle_put(handle);
- }
- }
-
- nv_wr32(priv, 0x00b100, stat);
- nv_wr32(priv, 0x00b230, 0x00000001);
-
- if (show) {
- nv_error(priv,
- "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
- chid, inst << 4, nouveau_client_name(engctx), stat,
- type, mthd, data);
- }
-
- nouveau_engctx_put(engctx);
-}
-
-static void
-nv44_mpeg_me_intr(struct nouveau_subdev *subdev)
-{
- struct nv44_mpeg_priv *priv = (void *)subdev;
- u32 stat;
-
- if ((stat = nv_rd32(priv, 0x00b100)))
- nv44_mpeg_intr(subdev);
-
- if ((stat = nv_rd32(priv, 0x00b800))) {
- nv_error(priv, "PMSRCH 0x%08x\n", stat);
- nv_wr32(priv, 0x00b800, stat);
- }
-}
-
-static int
-nv44_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv44_mpeg_priv *priv;
- int ret;
-
- ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- nv_subdev(priv)->unit = 0x00000002;
- nv_subdev(priv)->intr = nv44_mpeg_me_intr;
- nv_engine(priv)->cclass = &nv44_mpeg_cclass;
- nv_engine(priv)->sclass = nv40_mpeg_sclass;
- nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog;
- return 0;
-}
-
-struct nouveau_oclass
-nv44_mpeg_oclass = {
- .handle = NV_ENGINE(MPEG, 0x44),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv44_mpeg_ctor,
- .dtor = _nouveau_mpeg_dtor,
- .init = nv31_mpeg_init,
- .fini = _nouveau_mpeg_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c
deleted file mode 100644
index e9c5e51..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * 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 <core/option.h>
-#include <core/class.h>
-
-#include <subdev/clock.h>
-
-#include "priv.h"
-
-#define QUAD_MASK 0x0f
-#define QUAD_FREE 0x01
-
-static struct nouveau_perfsig *
-nouveau_perfsig_find_(struct nouveau_perfdom *dom, const char *name, u32 size)
-{
- char path[64];
- int i;
-
- if (name[0] != '/') {
- for (i = 0; i < dom->signal_nr; i++) {
- if ( dom->signal[i].name &&
- !strncmp(name, dom->signal[i].name, size))
- return &dom->signal[i];
- }
- } else {
- for (i = 0; i < dom->signal_nr; i++) {
- snprintf(path, sizeof(path), "/%s/%02x", dom->name, i);
- if (!strncmp(name, path, size))
- return &dom->signal[i];
- }
- }
-
- return NULL;
-}
-
-struct nouveau_perfsig *
-nouveau_perfsig_find(struct nouveau_perfmon *ppm, const char *name, u32 size,
- struct nouveau_perfdom **pdom)
-{
- struct nouveau_perfdom *dom = *pdom;
- struct nouveau_perfsig *sig;
-
- if (dom == NULL) {
- list_for_each_entry(dom, &ppm->domains, head) {
- sig = nouveau_perfsig_find_(dom, name, size);
- if (sig) {
- *pdom = dom;
- return sig;
- }
- }
-
- return NULL;
- }
-
- return nouveau_perfsig_find_(dom, name, size);
-}
-
-struct nouveau_perfctr *
-nouveau_perfsig_wrap(struct nouveau_perfmon *ppm, const char *name,
- struct nouveau_perfdom **pdom)
-{
- struct nouveau_perfsig *sig;
- struct nouveau_perfctr *ctr;
-
- sig = nouveau_perfsig_find(ppm, name, strlen(name), pdom);
- if (!sig)
- return NULL;
-
- ctr = kzalloc(sizeof(*ctr), GFP_KERNEL);
- if (ctr) {
- ctr->signal[0] = sig;
- ctr->logic_op = 0xaaaa;
- }
-
- return ctr;
-}
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-static int
-nouveau_perfctr_query(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
-{
- struct nouveau_device *device = nv_device(object);
- struct nouveau_perfmon *ppm = (void *)object->engine;
- struct nouveau_perfdom *dom = NULL, *chk;
- struct nv_perfctr_query *args = data;
- const bool all = nouveau_boolopt(device->cfgopt, "NvPmShowAll", false);
- const bool raw = nouveau_boolopt(device->cfgopt, "NvPmUnnamed", all);
- const char *name;
- int tmp = 0, di, si;
- char path[64];
-
- if (size < sizeof(*args))
- return -EINVAL;
-
- di = (args->iter & 0xff000000) >> 24;
- si = (args->iter & 0x00ffffff) - 1;
-
- list_for_each_entry(chk, &ppm->domains, head) {
- if (tmp++ == di) {
- dom = chk;
- break;
- }
- }
-
- if (dom == NULL || si >= (int)dom->signal_nr)
- return -EINVAL;
-
- if (si >= 0) {
- if (raw || !(name = dom->signal[si].name)) {
- snprintf(path, sizeof(path), "/%s/%02x", dom->name, si);
- name = path;
- }
-
- if (args->name)
- strncpy(args->name, name, args->size);
- args->size = strlen(name) + 1;
- }
-
- do {
- while (++si < dom->signal_nr) {
- if (all || dom->signal[si].name) {
- args->iter = (di << 24) | ++si;
- return 0;
- }
- }
- si = -1;
- di = di + 1;
- dom = list_entry(dom->head.next, typeof(*dom), head);
- } while (&dom->head != &ppm->domains);
-
- args->iter = 0xffffffff;
- return 0;
-}
-
-static int
-nouveau_perfctr_sample(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
-{
- struct nouveau_perfmon *ppm = (void *)object->engine;
- struct nouveau_perfctr *ctr, *tmp;
- struct nouveau_perfdom *dom;
- struct nv_perfctr_sample *args = data;
-
- if (size < sizeof(*args))
- return -EINVAL;
- ppm->sequence++;
-
- list_for_each_entry(dom, &ppm->domains, head) {
- /* sample previous batch of counters */
- if (dom->quad != QUAD_MASK) {
- dom->func->next(ppm, dom);
- tmp = NULL;
- while (!list_empty(&dom->list)) {
- ctr = list_first_entry(&dom->list,
- typeof(*ctr), head);
- if (ctr->slot < 0) break;
- if ( tmp && tmp == ctr) break;
- if (!tmp) tmp = ctr;
- dom->func->read(ppm, dom, ctr);
- ctr->slot = -1;
- list_move_tail(&ctr->head, &dom->list);
- }
- }
-
- dom->quad = QUAD_MASK;
-
- /* setup next batch of counters for sampling */
- list_for_each_entry(ctr, &dom->list, head) {
- ctr->slot = ffs(dom->quad) - 1;
- if (ctr->slot < 0)
- break;
- dom->quad &= ~(QUAD_FREE << ctr->slot);
- dom->func->init(ppm, dom, ctr);
- }
-
- if (dom->quad != QUAD_MASK)
- dom->func->next(ppm, dom);
- }
-
- return 0;
-}
-
-static int
-nouveau_perfctr_read(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
-{
- struct nouveau_perfctr *ctr = (void *)object;
- struct nv_perfctr_read *args = data;
-
- if (size < sizeof(*args))
- return -EINVAL;
- if (!ctr->clk)
- return -EAGAIN;
-
- args->clk = ctr->clk;
- args->ctr = ctr->ctr;
- return 0;
-}
-
-static void
-nouveau_perfctr_dtor(struct nouveau_object *object)
-{
- struct nouveau_perfctr *ctr = (void *)object;
- if (ctr->head.next)
- list_del(&ctr->head);
- nouveau_object_destroy(&ctr->base);
-}
-
-static int
-nouveau_perfctr_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nouveau_perfmon *ppm = (void *)engine;
- struct nouveau_perfdom *dom = NULL;
- struct nouveau_perfsig *sig[4] = {};
- struct nouveau_perfctr *ctr;
- struct nv_perfctr_class *args = data;
- int ret, i;
-
- if (size < sizeof(*args))
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(args->signal) && args->signal[i].name; i++) {
- sig[i] = nouveau_perfsig_find(ppm, args->signal[i].name,
- args->signal[i].size, &dom);
- if (!sig[i])
- return -EINVAL;
- }
-
- ret = nouveau_object_create(parent, engine, oclass, 0, &ctr);
- *pobject = nv_object(ctr);
- if (ret)
- return ret;
-
- ctr->slot = -1;
- ctr->logic_op = args->logic_op;
- ctr->signal[0] = sig[0];
- ctr->signal[1] = sig[1];
- ctr->signal[2] = sig[2];
- ctr->signal[3] = sig[3];
- if (dom)
- list_add_tail(&ctr->head, &dom->list);
- return 0;
-}
-
-static struct nouveau_ofuncs
-nouveau_perfctr_ofuncs = {
- .ctor = nouveau_perfctr_ctor,
- .dtor = nouveau_perfctr_dtor,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
-};
-
-static struct nouveau_omthds
-nouveau_perfctr_omthds[] = {
- { NV_PERFCTR_QUERY, NV_PERFCTR_QUERY, nouveau_perfctr_query },
- { NV_PERFCTR_SAMPLE, NV_PERFCTR_SAMPLE, nouveau_perfctr_sample },
- { NV_PERFCTR_READ, NV_PERFCTR_READ, nouveau_perfctr_read },
- {}
-};
-
-struct nouveau_oclass
-nouveau_perfmon_sclass[] = {
- { .handle = NV_PERFCTR_CLASS,
- .ofuncs = &nouveau_perfctr_ofuncs,
- .omthds = nouveau_perfctr_omthds,
- },
- {},
-};
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-static void
-nouveau_perfctx_dtor(struct nouveau_object *object)
-{
- struct nouveau_perfmon *ppm = (void *)object->engine;
- mutex_lock(&nv_subdev(ppm)->mutex);
- ppm->context = NULL;
- mutex_unlock(&nv_subdev(ppm)->mutex);
-}
-
-static int
-nouveau_perfctx_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nouveau_perfmon *ppm = (void *)engine;
- struct nouveau_perfctx *ctx;
- int ret;
-
- ret = nouveau_engctx_create(parent, engine, oclass, NULL,
- 0, 0, 0, &ctx);
- *pobject = nv_object(ctx);
- if (ret)
- return ret;
-
- mutex_lock(&nv_subdev(ppm)->mutex);
- if (ppm->context == NULL)
- ppm->context = ctx;
- mutex_unlock(&nv_subdev(ppm)->mutex);
-
- if (ctx != ppm->context)
- return -EBUSY;
-
- return 0;
-}
-
-struct nouveau_oclass
-nouveau_perfmon_cclass = {
- .handle = NV_ENGCTX(PERFMON, 0x00),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nouveau_perfctx_ctor,
- .dtor = nouveau_perfctx_dtor,
- .init = _nouveau_engctx_init,
- .fini = _nouveau_engctx_fini,
- },
-};
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-int
-nouveau_perfdom_new(struct nouveau_perfmon *ppm, const char *name, u32 mask,
- u32 base, u32 size_unit, u32 size_domain,
- const struct nouveau_specdom *spec)
-{
- const struct nouveau_specdom *sdom;
- const struct nouveau_specsig *ssig;
- struct nouveau_perfdom *dom;
- int i;
-
- for (i = 0; i == 0 || mask; i++) {
- u32 addr = base + (i * size_unit);
- if (i && !(mask & (1 << i)))
- continue;
-
- sdom = spec;
- while (sdom->signal_nr) {
- dom = kzalloc(sizeof(*dom) + sdom->signal_nr *
- sizeof(*dom->signal), GFP_KERNEL);
- if (!dom)
- return -ENOMEM;
-
- if (mask) {
- snprintf(dom->name, sizeof(dom->name),
- "%s/%02x/%02x", name, i,
- (int)(sdom - spec));
- } else {
- snprintf(dom->name, sizeof(dom->name),
- "%s/%02x", name, (int)(sdom - spec));
- }
-
- list_add_tail(&dom->head, &ppm->domains);
- INIT_LIST_HEAD(&dom->list);
- dom->func = sdom->func;
- dom->addr = addr;
- dom->quad = QUAD_MASK;
- dom->signal_nr = sdom->signal_nr;
-
- ssig = (sdom++)->signal;
- while (ssig->name) {
- dom->signal[ssig->signal].name = ssig->name;
- ssig++;
- }
-
- addr += size_domain;
- }
-
- mask &= ~(1 << i);
- }
-
- return 0;
-}
-
-int
-_nouveau_perfmon_fini(struct nouveau_object *object, bool suspend)
-{
- struct nouveau_perfmon *ppm = (void *)object;
- return nouveau_engine_fini(&ppm->base, suspend);
-}
-
-int
-_nouveau_perfmon_init(struct nouveau_object *object)
-{
- struct nouveau_perfmon *ppm = (void *)object;
- return nouveau_engine_init(&ppm->base);
-}
-
-void
-_nouveau_perfmon_dtor(struct nouveau_object *object)
-{
- struct nouveau_perfmon *ppm = (void *)object;
- struct nouveau_perfdom *dom, *tmp;
-
- list_for_each_entry_safe(dom, tmp, &ppm->domains, head) {
- list_del(&dom->head);
- kfree(dom);
- }
-
- nouveau_engine_destroy(&ppm->base);
-}
-
-int
-nouveau_perfmon_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int length, void **pobject)
-{
- struct nouveau_perfmon *ppm;
- int ret;
-
- ret = nouveau_engine_create_(parent, engine, oclass, true, "PPM",
- "perfmon", length, pobject);
- ppm = *pobject;
- if (ret)
- return ret;
-
- INIT_LIST_HEAD(&ppm->domains);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c
deleted file mode 100644
index 50696cc..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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 void
-pwr_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
-{
- u32 mask = 0x00000000;
- u32 ctrl = 0x00000001;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctr->signal) && ctr->signal[i]; i++)
- mask |= 1 << (ctr->signal[i] - dom->signal);
-
- nv_wr32(ppm, 0x10a504 + (ctr->slot * 0x10), mask);
- nv_wr32(ppm, 0x10a50c + (ctr->slot * 0x10), ctrl);
- nv_wr32(ppm, 0x10a50c + (ppm->last * 0x10), 0x00000003);
-}
-
-static void
-pwr_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
-{
- ctr->ctr = ppm->pwr[ctr->slot];
- ctr->clk = ppm->pwr[ppm->last];
-}
-
-static void
-pwr_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom)
-{
- int i;
-
- for (i = 0; i <= ppm->last; i++) {
- ppm->pwr[i] = nv_rd32(ppm, 0x10a508 + (i * 0x10));
- nv_wr32(ppm, 0x10a508 + (i * 0x10), 0x80000000);
- }
-}
-
-static const struct nouveau_funcdom
-pwr_perfctr_func = {
- .init = pwr_perfctr_init,
- .read = pwr_perfctr_read,
- .next = pwr_perfctr_next,
-};
-
-const struct nouveau_specdom
-nva3_perfmon_pwr[] = {
- { 0x20, (const struct nouveau_specsig[]) {
- { 0x00, "pwr_gr_idle" },
- { 0x04, "pwr_bsp_idle" },
- { 0x05, "pwr_vp_idle" },
- { 0x06, "pwr_ppp_idle" },
- { 0x13, "pwr_ce0_idle" },
- {}
- }, &pwr_perfctr_func },
- {}
-};
-
-const struct nouveau_specdom
-nvc0_perfmon_pwr[] = {
- { 0x20, (const struct nouveau_specsig[]) {
- { 0x00, "pwr_gr_idle" },
- { 0x04, "pwr_bsp_idle" },
- { 0x05, "pwr_vp_idle" },
- { 0x06, "pwr_ppp_idle" },
- { 0x13, "pwr_ce0_idle" },
- { 0x14, "pwr_ce1_idle" },
- {}
- }, &pwr_perfctr_func },
- {}
-};
-
-const struct nouveau_specdom
-nve0_perfmon_pwr[] = {
- { 0x20, (const struct nouveau_specsig[]) {
- { 0x00, "pwr_gr_idle" },
- { 0x04, "pwr_bsp_idle" },
- { 0x05, "pwr_vp_idle" },
- { 0x06, "pwr_ppp_idle" },
- { 0x13, "pwr_ce0_idle" },
- { 0x14, "pwr_ce1_idle" },
- { 0x15, "pwr_ce2_idle" },
- {}
- }, &pwr_perfctr_func },
- {}
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c
deleted file mode 100644
index b2a1078..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 "nv40.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static void
-nv40_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
-{
- struct nv40_perfmon_priv *priv = (void *)ppm;
- struct nv40_perfmon_cntr *cntr = (void *)ctr;
- u32 log = ctr->logic_op;
- u32 src = 0x00000000;
- int i;
-
- for (i = 0; i < 4 && ctr->signal[i]; i++)
- src |= (ctr->signal[i] - dom->signal) << (i * 8);
-
- nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001);
- nv_wr32(priv, 0x00a400 + dom->addr + (cntr->base.slot * 0x40), src);
- nv_wr32(priv, 0x00a420 + dom->addr + (cntr->base.slot * 0x40), log);
-}
-
-static void
-nv40_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
-{
- struct nv40_perfmon_priv *priv = (void *)ppm;
- struct nv40_perfmon_cntr *cntr = (void *)ctr;
-
- switch (cntr->base.slot) {
- case 0: cntr->base.ctr = nv_rd32(priv, 0x00a700 + dom->addr); break;
- case 1: cntr->base.ctr = nv_rd32(priv, 0x00a6c0 + dom->addr); break;
- case 2: cntr->base.ctr = nv_rd32(priv, 0x00a680 + dom->addr); break;
- case 3: cntr->base.ctr = nv_rd32(priv, 0x00a740 + dom->addr); break;
- }
- cntr->base.clk = nv_rd32(priv, 0x00a600 + dom->addr);
-}
-
-static void
-nv40_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom)
-{
- struct nv40_perfmon_priv *priv = (void *)ppm;
- if (priv->sequence != ppm->sequence) {
- nv_wr32(priv, 0x400084, 0x00000020);
- priv->sequence = ppm->sequence;
- }
-}
-
-const struct nouveau_funcdom
-nv40_perfctr_func = {
- .init = nv40_perfctr_init,
- .read = nv40_perfctr_read,
- .next = nv40_perfctr_next,
-};
-
-static const struct nouveau_specdom
-nv40_perfmon[] = {
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- {}
-};
-
-int
-nv40_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv40_perfmon_oclass *mclass = (void *)oclass;
- struct nv40_perfmon_priv *priv;
- int ret;
-
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- ret = nouveau_perfdom_new(&priv->base, "pm", 0, 0, 0, 4, mclass->doms);
- if (ret)
- return ret;
-
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
- return 0;
-}
-
-struct nouveau_oclass *
-nv40_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0x40),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
- },
- .doms = nv40_perfmon,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h
deleted file mode 100644
index 1b5792d..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __NVKM_PM_NV40_H__
-#define __NVKM_PM_NV40_H__
-
-#include "priv.h"
-
-struct nv40_perfmon_oclass {
- struct nouveau_oclass base;
- const struct nouveau_specdom *doms;
-};
-
-struct nv40_perfmon_priv {
- struct nouveau_perfmon base;
- u32 sequence;
-};
-
-int nv40_perfmon_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *data, u32 size,
- struct nouveau_object **pobject);
-
-struct nv40_perfmon_cntr {
- struct nouveau_perfctr base;
-};
-
-extern const struct nouveau_funcdom nv40_perfctr_func;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c
deleted file mode 100644
index 9421769..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 "nv40.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nv50_perfmon[] = {
- { 0x040, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x100, (const struct nouveau_specsig[]) {
- { 0xc8, "gr_idle" },
- {}
- }, &nv40_perfctr_func },
- { 0x100, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x020, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x040, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- {}
-};
-
-struct nouveau_oclass *
-nv50_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
- },
- .doms = nv50_perfmon,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c
deleted file mode 100644
index 9232c7f..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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 "nv40.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nv84_perfmon[] = {
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- {}
-};
-
-struct nouveau_oclass *
-nv84_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0x84),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
- },
- .doms = nv84_perfmon,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c
deleted file mode 100644
index 6197ebd..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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 "nv40.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nva3_perfmon[] = {
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- {}
-};
-
-static int
-nva3_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **object)
-{
- int ret = nv40_perfmon_ctor(parent, engine, oclass, data, size, object);
- if (ret == 0) {
- struct nv40_perfmon_priv *priv = (void *)*object;
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nva3_perfmon_pwr);
- if (ret)
- return ret;
-
- priv->base.last = 3;
- }
- return ret;
-}
-
-struct nouveau_oclass *
-nva3_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0xa3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
- },
- .doms = nva3_perfmon,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c
deleted file mode 100644
index 74b2410..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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 "nvc0.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nvc0_perfmon_hub[] = {
- {}
-};
-
-static const struct nouveau_specdom
-nvc0_perfmon_gpc[] = {
- {}
-};
-
-static const struct nouveau_specdom
-nvc0_perfmon_part[] = {
- {}
-};
-
-static void
-nvc0_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
-{
- struct nvc0_perfmon_priv *priv = (void *)ppm;
- struct nvc0_perfmon_cntr *cntr = (void *)ctr;
- u32 log = ctr->logic_op;
- u32 src = 0x00000000;
- int i;
-
- for (i = 0; i < 4 && ctr->signal[i]; i++)
- src |= (ctr->signal[i] - dom->signal) << (i * 8);
-
- nv_wr32(priv, dom->addr + 0x09c, 0x00040002);
- nv_wr32(priv, dom->addr + 0x100, 0x00000000);
- nv_wr32(priv, dom->addr + 0x040 + (cntr->base.slot * 0x08), src);
- nv_wr32(priv, dom->addr + 0x044 + (cntr->base.slot * 0x08), log);
-}
-
-static void
-nvc0_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
-{
- struct nvc0_perfmon_priv *priv = (void *)ppm;
- struct nvc0_perfmon_cntr *cntr = (void *)ctr;
-
- switch (cntr->base.slot) {
- case 0: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x08c); break;
- case 1: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x088); break;
- case 2: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x080); break;
- case 3: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x090); break;
- }
- cntr->base.clk = nv_rd32(priv, dom->addr + 0x070);
-}
-
-static void
-nvc0_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom)
-{
- struct nvc0_perfmon_priv *priv = (void *)ppm;
- nv_wr32(priv, dom->addr + 0x06c, dom->signal_nr - 0x40 + 0x27);
- nv_wr32(priv, dom->addr + 0x0ec, 0x00000011);
-}
-
-const struct nouveau_funcdom
-nvc0_perfctr_func = {
- .init = nvc0_perfctr_init,
- .read = nvc0_perfctr_read,
- .next = nvc0_perfctr_next,
-};
-
-int
-nvc0_perfmon_fini(struct nouveau_object *object, bool suspend)
-{
- struct nvc0_perfmon_priv *priv = (void *)object;
- nv_mask(priv, 0x000200, 0x10000000, 0x00000000);
- nv_mask(priv, 0x000200, 0x10000000, 0x10000000);
- return nouveau_perfmon_fini(&priv->base, suspend);
-}
-
-static int
-nvc0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_perfmon_priv *priv;
- u32 mask;
- int ret;
-
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nvc0_perfmon_pwr);
- if (ret)
- return ret;
-
- /* HUB */
- ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
- nvc0_perfmon_hub);
- if (ret)
- return ret;
-
- /* GPC */
- mask = (1 << nv_rd32(priv, 0x022430)) - 1;
- mask &= ~nv_rd32(priv, 0x022504);
- mask &= ~nv_rd32(priv, 0x022584);
-
- ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000,
- 0x1000, 0x200, nvc0_perfmon_gpc);
- if (ret)
- return ret;
-
- /* PART */
- mask = (1 << nv_rd32(priv, 0x022438)) - 1;
- mask &= ~nv_rd32(priv, 0x022548);
- mask &= ~nv_rd32(priv, 0x0225c8);
-
- ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000,
- 0x1000, 0x200, nvc0_perfmon_part);
- if (ret)
- return ret;
-
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
- priv->base.last = 7;
- return 0;
-}
-
-struct nouveau_oclass
-nvc0_perfmon_oclass = {
- .handle = NV_ENGINE(PERFMON, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = nvc0_perfmon_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h
deleted file mode 100644
index f66bca4..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __NVKM_PM_NVC0_H__
-#define __NVKM_PM_NVC0_H__
-
-#include "priv.h"
-
-struct nvc0_perfmon_priv {
- struct nouveau_perfmon base;
-};
-
-struct nvc0_perfmon_cntr {
- struct nouveau_perfctr base;
-};
-
-extern const struct nouveau_funcdom nvc0_perfctr_func;
-int nvc0_perfmon_fini(struct nouveau_object *, bool);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c
deleted file mode 100644
index 71d718c..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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 "nvc0.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nve0_perfmon_hub[] = {
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub00_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x40, (const struct nouveau_specsig[]) {
- { 0x27, "hub01_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub02_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub03_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x40, (const struct nouveau_specsig[]) {
- { 0x03, "host_mmio_rd" },
- { 0x27, "hub04_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub05_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0xc0, (const struct nouveau_specsig[]) {
- { 0x74, "host_fb_rd3x" },
- { 0x75, "host_fb_rd3x_2" },
- { 0xa7, "hub06_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub07_user_0" },
- {}
- }, &nvc0_perfctr_func },
- {}
-};
-
-static const struct nouveau_specdom
-nve0_perfmon_gpc[] = {
- { 0xe0, (const struct nouveau_specsig[]) {
- { 0xc7, "gpc00_user_0" },
- {}
- }, &nvc0_perfctr_func },
- {}
-};
-
-static const struct nouveau_specdom
-nve0_perfmon_part[] = {
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "part00_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "part01_user_0" },
- {}
- }, &nvc0_perfctr_func },
- {}
-};
-
-static int
-nve0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_perfmon_priv *priv;
- u32 mask;
- int ret;
-
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- /* PDAEMON */
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nve0_perfmon_pwr);
- if (ret)
- return ret;
-
- /* HUB */
- ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
- nve0_perfmon_hub);
- if (ret)
- return ret;
-
- /* GPC */
- mask = (1 << nv_rd32(priv, 0x022430)) - 1;
- mask &= ~nv_rd32(priv, 0x022504);
- mask &= ~nv_rd32(priv, 0x022584);
-
- ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000,
- 0x1000, 0x200, nve0_perfmon_gpc);
- if (ret)
- return ret;
-
- /* PART */
- mask = (1 << nv_rd32(priv, 0x022438)) - 1;
- mask &= ~nv_rd32(priv, 0x022548);
- mask &= ~nv_rd32(priv, 0x0225c8);
-
- ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000,
- 0x1000, 0x200, nve0_perfmon_part);
- if (ret)
- return ret;
-
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
- priv->base.last = 7;
- return 0;
-}
-
-struct nouveau_oclass
-nve0_perfmon_oclass = {
- .handle = NV_ENGINE(PERFMON, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = nvc0_perfmon_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c
deleted file mode 100644
index 47256f7..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 "nvc0.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static int
-nvf0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_perfmon_priv *priv;
- int ret;
-
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nve0_perfmon_pwr);
- if (ret)
- return ret;
-
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
- return 0;
-}
-
-struct nouveau_oclass
-nvf0_perfmon_oclass = {
- .handle = NV_ENGINE(PERFMON, 0xf0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvf0_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = nvc0_perfmon_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h
deleted file mode 100644
index 0ac8714..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef __NVKM_PERFMON_PRIV_H__
-#define __NVKM_PERFMON_PRIV_H__
-
-#include <engine/perfmon.h>
-
-struct nouveau_perfctr {
- struct nouveau_object base;
- struct list_head head;
- struct nouveau_perfsig *signal[4];
- int slot;
- u32 logic_op;
- u32 clk;
- u32 ctr;
-};
-
-extern struct nouveau_oclass nouveau_perfmon_sclass[];
-
-struct nouveau_perfctx {
- struct nouveau_engctx base;
-};
-
-extern struct nouveau_oclass nouveau_perfmon_cclass;
-
-struct nouveau_specsig {
- u8 signal;
- const char *name;
-};
-
-struct nouveau_perfsig {
- const char *name;
-};
-
-struct nouveau_perfdom;
-struct nouveau_perfctr *
-nouveau_perfsig_wrap(struct nouveau_perfmon *, const char *,
- struct nouveau_perfdom **);
-
-struct nouveau_specdom {
- u16 signal_nr;
- const struct nouveau_specsig *signal;
- const struct nouveau_funcdom *func;
-};
-
-extern const struct nouveau_specdom nva3_perfmon_pwr[];
-extern const struct nouveau_specdom nvc0_perfmon_pwr[];
-extern const struct nouveau_specdom nve0_perfmon_pwr[];
-
-struct nouveau_perfdom {
- struct list_head head;
- struct list_head list;
- const struct nouveau_funcdom *func;
- char name[32];
- u32 addr;
- u8 quad;
- u32 signal_nr;
- struct nouveau_perfsig signal[];
-};
-
-struct nouveau_funcdom {
- void (*init)(struct nouveau_perfmon *, struct nouveau_perfdom *,
- struct nouveau_perfctr *);
- void (*read)(struct nouveau_perfmon *, struct nouveau_perfdom *,
- struct nouveau_perfctr *);
- void (*next)(struct nouveau_perfmon *, struct nouveau_perfdom *);
-};
-
-int nouveau_perfdom_new(struct nouveau_perfmon *, const char *, u32,
- u32, u32, u32, const struct nouveau_specdom *);
-
-#define nouveau_perfmon_create(p,e,o,d) \
- nouveau_perfmon_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_perfmon_dtor(p) ({ \
- struct nouveau_perfmon *c = (p); \
- _nouveau_perfmon_dtor(nv_object(c)); \
-})
-#define nouveau_perfmon_init(p) ({ \
- struct nouveau_perfmon *c = (p); \
- _nouveau_perfmon_init(nv_object(c)); \
-})
-#define nouveau_perfmon_fini(p,s) ({ \
- struct nouveau_perfmon *c = (p); \
- _nouveau_perfmon_fini(nv_object(c), (s)); \
-})
-
-int nouveau_perfmon_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_perfmon_dtor(struct nouveau_object *);
-int _nouveau_perfmon_init(struct nouveau_object *);
-int _nouveau_perfmon_fini(struct nouveau_object *, bool);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c
index c571758..2a859a3 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c
@@ -135,8 +135,8 @@ nv04_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv04_software_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv04_software_oclass = {
.handle = NV_ENGINE(SW, 0x04),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_software_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c
index a62f11a..a019364 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c
@@ -117,8 +117,8 @@ nv10_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv10_software_oclass = &(struct nouveau_oclass) {
+struct nouveau_oclass
+nv10_software_oclass = {
.handle = NV_ENGINE(SW, 0x10),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv10_software_ctor,
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c
index 5ce686e..c48e749 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c
@@ -32,9 +32,16 @@
#include <subdev/bar.h>
+#include <engine/software.h>
#include <engine/disp.h>
-#include "nv50.h"
+struct nv50_software_priv {
+ struct nouveau_software base;
+};
+
+struct nv50_software_chan {
+ struct nouveau_software_chan base;
+};
/*******************************************************************************
* software object classes
@@ -55,7 +62,7 @@ nv50_software_mthd_dma_vblsem(struct nouveau_object *object, u32 mthd,
if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
struct nouveau_gpuobj *gpuobj = nv_gpuobj(handle->object);
- chan->vblank.ctxdma = gpuobj->node->offset >> 4;
+ chan->base.vblank.ctxdma = gpuobj->node->offset >> 4;
ret = 0;
}
nouveau_namedb_put(handle);
@@ -67,33 +74,34 @@ nv50_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd,
void *args, u32 size)
{
struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
- chan->vblank.offset = *(u32 *)args;
+ chan->base.vblank.offset = *(u32 *)args;
return 0;
}
-int
+static int
nv50_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd,
void *args, u32 size)
{
struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
- chan->vblank.value = *(u32 *)args;
+ chan->base.vblank.value = *(u32 *)args;
return 0;
}
-int
+static int
nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd,
void *args, u32 size)
{
struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
- u32 head = *(u32 *)args;
- if (head >= chan->vblank.nr_event)
+ struct nouveau_disp *disp = nouveau_disp(object);
+ u32 crtc = *(u32 *)args;
+ if (crtc > 1)
return -EINVAL;
- nouveau_event_get(chan->vblank.event[head]);
+ nouveau_event_get(disp->vblank, crtc, &chan->base.vblank.event);
return 0;
}
-int
+static int
nv50_software_mthd_flip(struct nouveau_object *object, u32 mthd,
void *args, u32 size)
{
@@ -124,9 +132,10 @@ nv50_software_sclass[] = {
******************************************************************************/
static int
-nv50_software_vblsem_release(void *data, int head)
+nv50_software_vblsem_release(struct nouveau_eventh *event, int head)
{
- struct nv50_software_chan *chan = data;
+ struct nouveau_software_chan *chan =
+ container_of(event, struct nouveau_software_chan, vblank.event);
struct nv50_software_priv *priv = (void *)nv_object(chan)->engine;
struct nouveau_bar *bar = nouveau_bar(priv);
@@ -145,76 +154,45 @@ nv50_software_vblsem_release(void *data, int head)
return NVKM_EVENT_DROP;
}
-void
-nv50_software_context_dtor(struct nouveau_object *object)
-{
- struct nv50_software_chan *chan = (void *)object;
- int i;
-
- if (chan->vblank.event) {
- for (i = 0; i < chan->vblank.nr_event; i++)
- nouveau_event_ref(NULL, &chan->vblank.event[i]);
- kfree(chan->vblank.event);
- }
-
- nouveau_software_context_destroy(&chan->base);
-}
-
-int
+static int
nv50_software_context_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nouveau_disp *pdisp = nouveau_disp(parent);
- struct nv50_software_cclass *pclass = (void *)oclass;
struct nv50_software_chan *chan;
- int ret, i;
+ int ret;
ret = nouveau_software_context_create(parent, engine, oclass, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- chan->vblank.nr_event = pdisp ? pdisp->vblank->index_nr : 0;
- chan->vblank.event = kzalloc(chan->vblank.nr_event *
- sizeof(*chan->vblank.event), GFP_KERNEL);
- if (!chan->vblank.event)
- return -ENOMEM;
-
- for (i = 0; i < chan->vblank.nr_event; i++) {
- ret = nouveau_event_new(pdisp->vblank, i, pclass->vblank,
- chan, &chan->vblank.event[i]);
- if (ret)
- return ret;
- }
-
- chan->vblank.channel = nv_gpuobj(parent->parent)->addr >> 12;
+ chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12;
+ chan->base.vblank.event.func = nv50_software_vblsem_release;
return 0;
}
-static struct nv50_software_cclass
+static struct nouveau_oclass
nv50_software_cclass = {
- .base.handle = NV_ENGCTX(SW, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .handle = NV_ENGCTX(SW, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_software_context_ctor,
.dtor = _nouveau_software_context_dtor,
.init = _nouveau_software_context_init,
.fini = _nouveau_software_context_fini,
},
- .vblank = nv50_software_vblsem_release,
};
/*******************************************************************************
* software engine/subdev functions
******************************************************************************/
-int
+static int
nv50_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv50_software_oclass *pclass = (void *)oclass;
struct nv50_software_priv *priv;
int ret;
@@ -223,21 +201,19 @@ nv50_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_engine(priv)->cclass = pclass->cclass;
- nv_engine(priv)->sclass = pclass->sclass;
+ nv_engine(priv)->cclass = &nv50_software_cclass;
+ nv_engine(priv)->sclass = nv50_software_sclass;
nv_subdev(priv)->intr = nv04_software_intr;
return 0;
}
-struct nouveau_oclass *
-nv50_software_oclass = &(struct nv50_software_oclass) {
- .base.handle = NV_ENGINE(SW, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass
+nv50_software_oclass = {
+ .handle = NV_ENGINE(SW, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_software_ctor,
.dtor = _nouveau_software_dtor,
.init = _nouveau_software_init,
.fini = _nouveau_software_fini,
},
- .cclass = &nv50_software_cclass.base,
- .sclass = nv50_software_sclass,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h
deleted file mode 100644
index 2de370c..0000000
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __NVKM_SW_NV50_H__
-#define __NVKM_SW_NV50_H__
-
-#include <engine/software.h>
-
-struct nv50_software_oclass {
- struct nouveau_oclass base;
- struct nouveau_oclass *cclass;
- struct nouveau_oclass *sclass;
-};
-
-struct nv50_software_priv {
- struct nouveau_software base;
-};
-
-int nv50_software_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-struct nv50_software_cclass {
- struct nouveau_oclass base;
- int (*vblank)(void *, int);
-};
-
-struct nv50_software_chan {
- struct nouveau_software_chan base;
- struct {
- struct nouveau_eventh **event;
- int nr_event;
- u32 channel;
- u32 ctxdma;
- u64 offset;
- u32 value;
- } vblank;
-};
-
-int nv50_software_context_ctor(struct nouveau_object *,
- struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv50_software_context_dtor(struct nouveau_object *);
-
-int nv50_software_mthd_vblsem_value(struct nouveau_object *, u32, void *, u32);
-int nv50_software_mthd_vblsem_release(struct nouveau_object *, u32, void *, u32);
-int nv50_software_mthd_flip(struct nouveau_object *, u32, void *, u32);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
index f9430c1..d698e71 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
@@ -32,7 +32,13 @@
#include <engine/software.h>
#include <engine/disp.h>
-#include "nv50.h"
+struct nvc0_software_priv {
+ struct nouveau_software base;
+};
+
+struct nvc0_software_chan {
+ struct nouveau_software_chan base;
+};
/*******************************************************************************
* software object classes
@@ -42,24 +48,58 @@ static int
nvc0_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd,
void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
u64 data = *(u32 *)args;
if (mthd == 0x0400) {
- chan->vblank.offset &= 0x00ffffffffULL;
- chan->vblank.offset |= data << 32;
+ chan->base.vblank.offset &= 0x00ffffffffULL;
+ chan->base.vblank.offset |= data << 32;
} else {
- chan->vblank.offset &= 0xff00000000ULL;
- chan->vblank.offset |= data;
+ chan->base.vblank.offset &= 0xff00000000ULL;
+ chan->base.vblank.offset |= data;
}
return 0;
}
static int
+nvc0_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ chan->base.vblank.value = *(u32 *)args;
+ return 0;
+}
+
+static int
+nvc0_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nouveau_disp *disp = nouveau_disp(object);
+ u32 crtc = *(u32 *)args;
+
+ if ((nv_device(object)->card_type < NV_E0 && crtc > 1) || crtc > 3)
+ return -EINVAL;
+
+ nouveau_event_get(disp->vblank, crtc, &chan->base.vblank.event);
+ return 0;
+}
+
+static int
+nvc0_software_mthd_flip(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ if (chan->base.flip)
+ return chan->base.flip(chan->base.flip_data);
+ return -EINVAL;
+}
+
+static int
nvc0_software_mthd_mp_control(struct nouveau_object *object, u32 mthd,
void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
- struct nv50_software_priv *priv = (void *)nv_object(chan)->engine;
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine;
u32 data = *(u32 *)args;
switch (mthd) {
@@ -84,9 +124,9 @@ static struct nouveau_omthds
nvc0_software_omthds[] = {
{ 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset },
{ 0x0404, 0x0404, nvc0_software_mthd_vblsem_offset },
- { 0x0408, 0x0408, nv50_software_mthd_vblsem_value },
- { 0x040c, 0x040c, nv50_software_mthd_vblsem_release },
- { 0x0500, 0x0500, nv50_software_mthd_flip },
+ { 0x0408, 0x0408, nvc0_software_mthd_vblsem_value },
+ { 0x040c, 0x040c, nvc0_software_mthd_vblsem_release },
+ { 0x0500, 0x0500, nvc0_software_mthd_flip },
{ 0x0600, 0x0600, nvc0_software_mthd_mp_control },
{ 0x0644, 0x0644, nvc0_software_mthd_mp_control },
{ 0x06ac, 0x06ac, nvc0_software_mthd_mp_control },
@@ -104,10 +144,11 @@ nvc0_software_sclass[] = {
******************************************************************************/
static int
-nvc0_software_vblsem_release(void *data, int head)
+nvc0_software_vblsem_release(struct nouveau_eventh *event, int head)
{
- struct nv50_software_chan *chan = data;
- struct nv50_software_priv *priv = (void *)nv_object(chan)->engine;
+ struct nouveau_software_chan *chan =
+ container_of(event, struct nouveau_software_chan, vblank.event);
+ struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine;
struct nouveau_bar *bar = nouveau_bar(priv);
nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
@@ -119,31 +160,66 @@ nvc0_software_vblsem_release(void *data, int head)
return NVKM_EVENT_DROP;
}
-static struct nv50_software_cclass
+static int
+nvc0_software_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_software_chan *chan;
+ int ret;
+
+ ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12;
+ chan->base.vblank.event.func = nvc0_software_vblsem_release;
+ return 0;
+}
+
+static struct nouveau_oclass
nvc0_software_cclass = {
- .base.handle = NV_ENGCTX(SW, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_software_context_ctor,
+ .handle = NV_ENGCTX(SW, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_software_context_ctor,
.dtor = _nouveau_software_context_dtor,
.init = _nouveau_software_context_init,
.fini = _nouveau_software_context_fini,
},
- .vblank = nvc0_software_vblsem_release,
};
/*******************************************************************************
* software engine/subdev functions
******************************************************************************/
-struct nouveau_oclass *
-nvc0_software_oclass = &(struct nv50_software_oclass) {
- .base.handle = NV_ENGINE(SW, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_software_ctor,
+static int
+nvc0_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_software_priv *priv;
+ int ret;
+
+ ret = nouveau_software_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->cclass = &nvc0_software_cclass;
+ nv_engine(priv)->sclass = nvc0_software_sclass;
+ nv_subdev(priv)->intr = nv04_software_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_software_oclass = {
+ .handle = NV_ENGINE(SW, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_software_ctor,
.dtor = _nouveau_software_dtor,
.init = _nouveau_software_init,
.fini = _nouveau_software_fini,
},
- .cclass = &nvc0_software_cclass.base,
- .sclass = nvc0_software_sclass,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h
index 560c359..5a5961b 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/class.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/class.h
@@ -22,7 +22,7 @@
#define NV_DEVICE_DISABLE_PPP 0x0000004000000000ULL
#define NV_DEVICE_DISABLE_COPY0 0x0000008000000000ULL
#define NV_DEVICE_DISABLE_COPY1 0x0000010000000000ULL
-#define NV_DEVICE_DISABLE_VIC 0x0000020000000000ULL
+#define NV_DEVICE_DISABLE_UNK1C1 0x0000020000000000ULL
#define NV_DEVICE_DISABLE_VENC 0x0000040000000000ULL
struct nv_device_class {
@@ -98,77 +98,6 @@ struct nv_dma_class {
u32 conf0;
};
-/* Perfmon counter class
- *
- * XXXX: NV_PERFCTR
- */
-#define NV_PERFCTR_CLASS 0x0000ffff
-#define NV_PERFCTR_QUERY 0x00000000
-#define NV_PERFCTR_SAMPLE 0x00000001
-#define NV_PERFCTR_READ 0x00000002
-
-struct nv_perfctr_class {
- u16 logic_op;
- struct {
- char __user *name; /*XXX: use cfu when exposed to userspace */
- u32 size;
- } signal[4];
-};
-
-struct nv_perfctr_query {
- u32 iter;
- u32 size;
- char __user *name; /*XXX: use ctu when exposed to userspace */
-};
-
-struct nv_perfctr_sample {
-};
-
-struct nv_perfctr_read {
- u32 ctr;
- u32 clk;
-};
-
-/* Device control class
- *
- * XXXX: NV_CONTROL
- */
-#define NV_CONTROL_CLASS 0x0000fffe
-
-#define NV_CONTROL_PSTATE_INFO 0x00000000
-#define NV_CONTROL_PSTATE_INFO_USTATE_DISABLE (-1)
-#define NV_CONTROL_PSTATE_INFO_USTATE_PERFMON (-2)
-#define NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN (-1)
-#define NV_CONTROL_PSTATE_INFO_PSTATE_PERFMON (-2)
-#define NV_CONTROL_PSTATE_ATTR 0x00000001
-#define NV_CONTROL_PSTATE_ATTR_STATE_CURRENT (-1)
-#define NV_CONTROL_PSTATE_USER 0x00000002
-#define NV_CONTROL_PSTATE_USER_STATE_UNKNOWN (-1)
-#define NV_CONTROL_PSTATE_USER_STATE_PERFMON (-2)
-
-struct nv_control_pstate_info {
- u32 count; /* out: number of power states */
- s32 ustate; /* out: current target pstate index */
- u32 pstate; /* out: current pstate index */
-};
-
-struct nv_control_pstate_attr {
- s32 state; /* in: index of pstate to query
- * out: pstate identifier
- */
- u32 index; /* in: index of attribute to query
- * out: index of next attribute, or 0 if no more
- */
- char name[32];
- char unit[16];
- u32 min;
- u32 max;
-};
-
-struct nv_control_pstate_user {
- s32 state; /* in: pstate identifier */
-};
-
/* DMA FIFO channel classes
*
* 006b: NV03_CHANNEL_DMA
diff --git a/drivers/gpu/drm/nouveau/core/include/core/debug.h b/drivers/gpu/drm/nouveau/core/include/core/debug.h
index 8092e2e..9ea18df 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/debug.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/debug.h
@@ -1,20 +1,13 @@
#ifndef __NOUVEAU_DEBUG_H__
#define __NOUVEAU_DEBUG_H__
-extern int nv_info_debug_level;
-
#define NV_DBG_FATAL 0
#define NV_DBG_ERROR 1
#define NV_DBG_WARN 2
-#define NV_DBG_INFO nv_info_debug_level
+#define NV_DBG_INFO 3
#define NV_DBG_DEBUG 4
#define NV_DBG_TRACE 5
#define NV_DBG_PARANOIA 6
#define NV_DBG_SPAM 7
-#define NV_DBG_INFO_NORMAL 3
-#define NV_DBG_INFO_SILENT NV_DBG_DEBUG
-
-#define nv_debug_level(a) nv_info_debug_level = NV_DBG_INFO_##a
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
index ac2881d..99b6600 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -33,10 +33,9 @@ enum nv_subdev_type {
NVDEV_SUBDEV_INSTMEM,
NVDEV_SUBDEV_VM,
NVDEV_SUBDEV_BAR,
- NVDEV_SUBDEV_PWR,
NVDEV_SUBDEV_VOLT,
- NVDEV_SUBDEV_THERM,
NVDEV_SUBDEV_CLOCK,
+ NVDEV_SUBDEV_THERM,
NVDEV_ENGINE_DMAOBJ,
NVDEV_ENGINE_FIFO,
@@ -51,10 +50,9 @@ enum nv_subdev_type {
NVDEV_ENGINE_COPY0,
NVDEV_ENGINE_COPY1,
NVDEV_ENGINE_COPY2,
- NVDEV_ENGINE_VIC,
+ NVDEV_ENGINE_UNK1C1,
NVDEV_ENGINE_VENC,
NVDEV_ENGINE_DISP,
- NVDEV_ENGINE_PERFMON,
NVDEV_SUBDEV_NR,
};
@@ -74,7 +72,6 @@ struct nouveau_device {
enum {
NV_04 = 0x04,
NV_10 = 0x10,
- NV_11 = 0x11,
NV_20 = 0x20,
NV_30 = 0x30,
NV_40 = 0x40,
diff --git a/drivers/gpu/drm/nouveau/core/include/core/event.h b/drivers/gpu/drm/nouveau/core/include/core/event.h
index 5d539eb..9e09440 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/event.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/event.h
@@ -5,21 +5,13 @@
#define NVKM_EVENT_DROP 0
#define NVKM_EVENT_KEEP 1
-/* nouveau_eventh.flags bit #s */
-#define NVKM_EVENT_ENABLE 0
-
struct nouveau_eventh {
- struct nouveau_event *event;
struct list_head head;
- unsigned long flags;
- int index;
- int (*func)(void *, int);
- void *priv;
+ int (*func)(struct nouveau_eventh *, int index);
};
struct nouveau_event {
- spinlock_t list_lock;
- spinlock_t refs_lock;
+ spinlock_t lock;
void *priv;
void (*enable)(struct nouveau_event *, int index);
@@ -36,11 +28,9 @@ int nouveau_event_create(int index_nr, struct nouveau_event **);
void nouveau_event_destroy(struct nouveau_event **);
void nouveau_event_trigger(struct nouveau_event *, int index);
-int nouveau_event_new(struct nouveau_event *, int index,
- int (*func)(void *, int), void *,
- struct nouveau_eventh **);
-void nouveau_event_ref(struct nouveau_eventh *, struct nouveau_eventh **);
-void nouveau_event_get(struct nouveau_eventh *);
-void nouveau_event_put(struct nouveau_eventh *);
+void nouveau_event_get(struct nouveau_event *, int index,
+ struct nouveau_eventh *);
+void nouveau_event_put(struct nouveau_event *, int index,
+ struct nouveau_eventh *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/option.h b/drivers/gpu/drm/nouveau/core/include/core/option.h
index ed05584..2707495 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/option.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/option.h
@@ -8,13 +8,4 @@ bool nouveau_boolopt(const char *optstr, const char *opt, bool value);
int nouveau_dbgopt(const char *optstr, const char *sub);
-/* compares unterminated string 'str' with zero-terminated string 'cmp' */
-static inline int
-strncasecmpz(const char *str, const char *cmp, size_t len)
-{
- if (strlen(cmp) != len)
- return len;
- return strncasecmp(str, cmp, len);
-}
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/printk.h b/drivers/gpu/drm/nouveau/core/include/core/printk.h
index 0f9a37b..d87836e 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/printk.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/printk.h
@@ -6,12 +6,27 @@
struct nouveau_object;
-void __printf(3, 4)
-nv_printk_(struct nouveau_object *, int, const char *, ...);
+#define NV_PRINTK_FATAL KERN_CRIT
+#define NV_PRINTK_ERROR KERN_ERR
+#define NV_PRINTK_WARN KERN_WARNING
+#define NV_PRINTK_INFO KERN_INFO
+#define NV_PRINTK_DEBUG KERN_DEBUG
+#define NV_PRINTK_PARANOIA KERN_DEBUG
+#define NV_PRINTK_TRACE KERN_DEBUG
+#define NV_PRINTK_SPAM KERN_DEBUG
+
+extern int nv_printk_suspend_level;
+
+#define NV_DBG_SUSPEND (nv_printk_suspend_level)
+#define NV_PRINTK_SUSPEND (nv_printk_level_to_pfx(nv_printk_suspend_level))
+
+const char *nv_printk_level_to_pfx(int level);
+void __printf(4, 5)
+nv_printk_(struct nouveau_object *, const char *, int, const char *, ...);
#define nv_printk(o,l,f,a...) do { \
if (NV_DBG_##l <= CONFIG_NOUVEAU_DEBUG) \
- nv_printk_(nv_object(o), NV_DBG_##l, f, ##a); \
+ nv_printk_(nv_object(o), NV_PRINTK_##l, NV_DBG_##l, f, ##a); \
} while(0)
#define nv_fatal(o,f,a...) nv_printk((o), FATAL, f, ##a)
@@ -22,9 +37,16 @@ nv_printk_(struct nouveau_object *, int, const char *, ...);
#define nv_trace(o,f,a...) nv_printk((o), TRACE, f, ##a)
#define nv_spam(o,f,a...) nv_printk((o), SPAM, f, ##a)
+#define nv_suspend(o,f,a...) nv_printk((o), SUSPEND, f, ##a)
+
+static inline void nv_suspend_set_printk_level(int level)
+{
+ nv_printk_suspend_level = level;
+}
+
#define nv_assert(f,a...) do { \
if (NV_DBG_FATAL <= CONFIG_NOUVEAU_DEBUG) \
- nv_printk_(NULL, NV_DBG_FATAL, f "\n", ##a); \
+ nv_printk_(NULL, NV_PRINTK_FATAL, NV_DBG_FATAL, f "\n", ##a); \
BUG_ON(1); \
} while(0)
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
index 8c32cf4..633c2f8 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
@@ -101,14 +101,14 @@ nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid);
#define _nouveau_fifo_init _nouveau_engine_init
#define _nouveau_fifo_fini _nouveau_engine_fini
-extern struct nouveau_oclass *nv04_fifo_oclass;
-extern struct nouveau_oclass *nv10_fifo_oclass;
-extern struct nouveau_oclass *nv17_fifo_oclass;
-extern struct nouveau_oclass *nv40_fifo_oclass;
-extern struct nouveau_oclass *nv50_fifo_oclass;
-extern struct nouveau_oclass *nv84_fifo_oclass;
-extern struct nouveau_oclass *nvc0_fifo_oclass;
-extern struct nouveau_oclass *nve0_fifo_oclass;
+extern struct nouveau_oclass nv04_fifo_oclass;
+extern struct nouveau_oclass nv10_fifo_oclass;
+extern struct nouveau_oclass nv17_fifo_oclass;
+extern struct nouveau_oclass nv40_fifo_oclass;
+extern struct nouveau_oclass nv50_fifo_oclass;
+extern struct nouveau_oclass nv84_fifo_oclass;
+extern struct nouveau_oclass nvc0_fifo_oclass;
+extern struct nouveau_oclass nve0_fifo_oclass;
void nv04_fifo_intr(struct nouveau_subdev *);
int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *);
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
index 9b0d938..1d1a89a 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
@@ -42,13 +42,10 @@ struct nouveau_mpeg {
extern struct nouveau_oclass nv31_mpeg_oclass;
extern struct nouveau_oclass nv40_mpeg_oclass;
-extern struct nouveau_oclass nv44_mpeg_oclass;
extern struct nouveau_oclass nv50_mpeg_oclass;
extern struct nouveau_oclass nv84_mpeg_oclass;
-extern struct nouveau_ofuncs nv31_mpeg_ofuncs;
-extern struct nouveau_oclass nv31_mpeg_cclass;
+
extern struct nouveau_oclass nv31_mpeg_sclass[];
-extern struct nouveau_oclass nv40_mpeg_sclass[];
void nv31_mpeg_intr(struct nouveau_subdev *);
void nv31_mpeg_tile_prog(struct nouveau_engine *, int);
int nv31_mpeg_init(struct nouveau_object *);
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h b/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h
deleted file mode 100644
index 49b0024..0000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __NVKM_PERFMON_H__
-#define __NVKM_PERFMON_H__
-
-#include <core/device.h>
-#include <core/engine.h>
-#include <core/engctx.h>
-#include <core/class.h>
-
-struct nouveau_perfdom;
-struct nouveau_perfctr;
-struct nouveau_perfmon {
- struct nouveau_engine base;
-
- struct nouveau_perfctx *context;
- void *profile_data;
-
- struct list_head domains;
- u32 sequence;
-
- /*XXX: temp for daemon backend */
- u32 pwr[8];
- u32 last;
-};
-
-static inline struct nouveau_perfmon *
-nouveau_perfmon(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_PERFMON];
-}
-
-extern struct nouveau_oclass *nv40_perfmon_oclass;
-extern struct nouveau_oclass *nv50_perfmon_oclass;
-extern struct nouveau_oclass *nv84_perfmon_oclass;
-extern struct nouveau_oclass *nva3_perfmon_oclass;
-extern struct nouveau_oclass nvc0_perfmon_oclass;
-extern struct nouveau_oclass nve0_perfmon_oclass;
-extern struct nouveau_oclass nvf0_perfmon_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/software.h b/drivers/gpu/drm/nouveau/core/include/engine/software.h
index 23a462b..4579948 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/software.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/software.h
@@ -3,10 +3,19 @@
#include <core/engine.h>
#include <core/engctx.h>
+#include <core/event.h>
struct nouveau_software_chan {
struct nouveau_engctx base;
+ struct {
+ struct nouveau_eventh event;
+ u32 channel;
+ u32 ctxdma;
+ u64 offset;
+ u32 value;
+ } vblank;
+
int (*flip)(void *);
void *flip_data;
};
@@ -41,10 +50,10 @@ struct nouveau_software {
#define _nouveau_software_init _nouveau_engine_init
#define _nouveau_software_fini _nouveau_engine_fini
-extern struct nouveau_oclass *nv04_software_oclass;
-extern struct nouveau_oclass *nv10_software_oclass;
-extern struct nouveau_oclass *nv50_software_oclass;
-extern struct nouveau_oclass *nvc0_software_oclass;
+extern struct nouveau_oclass nv04_software_oclass;
+extern struct nouveau_oclass nv10_software_oclass;
+extern struct nouveau_oclass nv50_software_oclass;
+extern struct nouveau_oclass nvc0_software_oclass;
void nv04_software_intr(struct nouveau_subdev *);
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h
deleted file mode 100644
index 662b207..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __NVBIOS_BOOST_H__
-#define __NVBIOS_BOOST_H__
-
-u16 nvbios_boostTe(struct nouveau_bios *, u8 *, u8 *, u8 *, u8 *, u8 *, u8 *);
-
-struct nvbios_boostE {
- u8 pstate;
- u32 min;
- u32 max;
-};
-
-u16 nvbios_boostEe(struct nouveau_bios *, int idx, u8 *, u8 *, u8 *, u8 *);
-u16 nvbios_boostEp(struct nouveau_bios *, int idx, u8 *, u8 *, u8 *, u8 *,
- struct nvbios_boostE *);
-u16 nvbios_boostEm(struct nouveau_bios *, u8, u8 *, u8 *, u8 *, u8 *,
- struct nvbios_boostE *);
-
-struct nvbios_boostS {
- u8 domain;
- u8 percent;
- u32 min;
- u32 max;
-};
-
-u16 nvbios_boostSe(struct nouveau_bios *, int, u16, u8 *, u8 *, u8, u8);
-u16 nvbios_boostSp(struct nouveau_bios *, int, u16, u8 *, u8 *, u8, u8,
- struct nvbios_boostS *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h
deleted file mode 100644
index a80a4380..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __NVBIOS_CSTEP_H__
-#define __NVBIOS_CSTEP_H__
-
-u16 nvbios_cstepTe(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
-
-struct nvbios_cstepE {
- u8 pstate;
- u8 index;
-};
-
-u16 nvbios_cstepEe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u16 nvbios_cstepEp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
- struct nvbios_cstepE *);
-u16 nvbios_cstepEm(struct nouveau_bios *, u8 pstate, u8 *ver, u8 *hdr,
- struct nvbios_cstepE *);
-
-struct nvbios_cstepX {
- u32 freq;
- u8 unkn[2];
- u8 voltage;
-};
-
-u16 nvbios_cstepXe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u16 nvbios_cstepXp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
- struct nvbios_cstepX *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
index c7b2e58..96d3364 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
@@ -7,15 +7,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_TVDAC1 = 0x2d,
DCB_GPIO_FAN = 0x09,
DCB_GPIO_FAN_SENSE = 0x3d,
- DCB_GPIO_UNUSED = 0xff,
- DCB_GPIO_VID0 = 0x04,
- DCB_GPIO_VID1 = 0x05,
- DCB_GPIO_VID2 = 0x06,
- DCB_GPIO_VID3 = 0x1a,
- DCB_GPIO_VID4 = 0x73,
- DCB_GPIO_VID5 = 0x74,
- DCB_GPIO_VID6 = 0x75,
- DCB_GPIO_VID7 = 0x76,
+ DCB_GPIO_UNUSED = 0xff
};
#define DCB_GPIO_LOG_DIR 0x02
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h
index 16ff06e..0b285e9 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h
@@ -3,39 +3,6 @@
struct nouveau_bios;
-u16 nvbios_perf_table(struct nouveau_bios *, u8 *ver, u8 *hdr,
- u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
-
-struct nvbios_perfE {
- u8 pstate;
- u8 fanspeed;
- u8 voltage;
- u32 core;
- u32 shader;
- u32 memory;
- u32 vdec;
- u32 disp;
- u32 script;
-};
-
-u16 nvbios_perf_entry(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_perfEp(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_perfE *);
-
-struct nvbios_perfS {
- union {
- struct {
- u32 freq;
- } v40;
- };
-};
-
-u32 nvbios_perfSe(struct nouveau_bios *, u32 data, int idx,
- u8 *ver, u8 *hdr, u8 cnt, u8 len);
-u32 nvbios_perfSp(struct nouveau_bios *, u32 data, int idx,
- u8 *ver, u8 *hdr, u8 cnt, u8 len, struct nvbios_perfS *);
-
struct nvbios_perf_fan {
u32 pwm_divisor;
};
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h
deleted file mode 100644
index bc15e03..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __NVBIOS_RAMMAP_H__
-#define __NVBIOS_RAMMAP_H__
-
-u16 nvbios_rammap_table(struct nouveau_bios *, u8 *ver, u8 *hdr,
- u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
-u16 nvbios_rammap_entry(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_rammap_match(struct nouveau_bios *, u16 khz,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h
deleted file mode 100644
index 963694b..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __NVBIOS_TIMING_H__
-#define __NVBIOS_TIMING_H__
-
-u16 nvbios_timing_table(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_timing_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h
deleted file mode 100644
index ad5a8f2..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __NVBIOS_VMAP_H__
-#define __NVBIOS_VMAP_H__
-
-struct nouveau_bios;
-
-struct nvbios_vmap {
-};
-
-u16 nvbios_vmap_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_vmap_parse(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_vmap *);
-
-struct nvbios_vmap_entry {
- u8 unk0;
- u8 link;
- u32 min;
- u32 max;
- s32 arg[6];
-};
-
-u16 nvbios_vmap_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *len);
-u16 nvbios_vmap_entry_parse(struct nouveau_bios *, int idx, u8 *ver, u8 *len,
- struct nvbios_vmap_entry *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h
deleted file mode 100644
index 6a11dcd..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __NVBIOS_VOLT_H__
-#define __NVBIOS_VOLT_H__
-
-struct nouveau_bios;
-
-struct nvbios_volt {
- u8 vidmask;
- u32 min;
- u32 max;
- u32 base;
- s16 step;
-};
-
-u16 nvbios_volt_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_volt_parse(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_volt *);
-
-struct nvbios_volt_entry {
- u32 voltage;
- u8 vid;
-};
-
-u16 nvbios_volt_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *len);
-u16 nvbios_volt_entry_parse(struct nouveau_bios *, int idx, u8 *ver, u8 *len,
- struct nvbios_volt_entry *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bus.h b/drivers/gpu/drm/nouveau/core/include/subdev/bus.h
index 697f7ce..7d88ec4 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bus.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bus.h
@@ -11,8 +11,6 @@ struct nouveau_bus_intr {
struct nouveau_bus {
struct nouveau_subdev base;
- int (*hwsq_exec)(struct nouveau_bus *, u32 *, u32);
- u32 hwsq_size;
};
static inline struct nouveau_bus *
@@ -35,19 +33,9 @@ nouveau_bus(void *obj)
#define _nouveau_bus_init _nouveau_subdev_init
#define _nouveau_bus_fini _nouveau_subdev_fini
-extern struct nouveau_oclass *nv04_bus_oclass;
-extern struct nouveau_oclass *nv31_bus_oclass;
-extern struct nouveau_oclass *nv50_bus_oclass;
-extern struct nouveau_oclass *nv94_bus_oclass;
-extern struct nouveau_oclass *nvc0_bus_oclass;
-
-/* interface to sequencer */
-struct nouveau_hwsq;
-int nouveau_hwsq_init(struct nouveau_bus *, struct nouveau_hwsq **);
-int nouveau_hwsq_fini(struct nouveau_hwsq **, bool exec);
-void nouveau_hwsq_wr32(struct nouveau_hwsq *, u32 addr, u32 data);
-void nouveau_hwsq_setf(struct nouveau_hwsq *, u8 flag, int data);
-void nouveau_hwsq_wait(struct nouveau_hwsq *, u8 flag, u8 data);
-void nouveau_hwsq_nsec(struct nouveau_hwsq *, u32 nsec);
+extern struct nouveau_oclass nv04_bus_oclass;
+extern struct nouveau_oclass nv31_bus_oclass;
+extern struct nouveau_oclass nv50_bus_oclass;
+extern struct nouveau_oclass nvc0_bus_oclass;
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
index 8f4ced7..89ee289 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
@@ -7,81 +7,9 @@
struct nouveau_pll_vals;
struct nvbios_pll;
-enum nv_clk_src {
- nv_clk_src_crystal,
- nv_clk_src_href,
-
- nv_clk_src_hclk,
- nv_clk_src_hclkm3,
- nv_clk_src_hclkm3d2,
- nv_clk_src_hclkm2d3, /* NVAA */
- nv_clk_src_hclkm4, /* NVAA */
- nv_clk_src_cclk, /* NVAA */
-
- nv_clk_src_host,
-
- nv_clk_src_sppll0,
- nv_clk_src_sppll1,
-
- nv_clk_src_mpllsrcref,
- nv_clk_src_mpllsrc,
- nv_clk_src_mpll,
- nv_clk_src_mdiv,
-
- nv_clk_src_core,
- nv_clk_src_shader,
-
- nv_clk_src_mem,
-
- nv_clk_src_gpc,
- nv_clk_src_rop,
- nv_clk_src_hubk01,
- nv_clk_src_hubk06,
- nv_clk_src_hubk07,
- nv_clk_src_copy,
- nv_clk_src_daemon,
- nv_clk_src_disp,
- nv_clk_src_vdec,
-
- nv_clk_src_dom6,
-
- nv_clk_src_max,
-};
-
-struct nouveau_cstate {
- struct list_head head;
- u8 voltage;
- u32 domain[nv_clk_src_max];
-};
-
-struct nouveau_pstate {
- struct list_head head;
- struct list_head list; /* c-states */
- struct nouveau_cstate base;
- u8 pstate;
- u8 fanspeed;
-};
-
struct nouveau_clock {
struct nouveau_subdev base;
- struct nouveau_clocks *domains;
- struct nouveau_pstate bstate;
-
- struct list_head states;
- int state_nr;
-
- int pstate; /* current */
- int ustate; /* user-requested (-1 disabled, -2 perfmon) */
- int astate; /* perfmon adjustment (base) */
- int tstate; /* thermal adjustment (max-) */
- int dstate; /* display adjustment (min+) */
-
- int (*read)(struct nouveau_clock *, enum nv_clk_src);
- int (*calc)(struct nouveau_clock *, struct nouveau_cstate *);
- int (*prog)(struct nouveau_clock *);
- void (*tidy)(struct nouveau_clock *);
-
/*XXX: die, these are here *only* to support the completely
* bat-shit insane what-was-nouveau_hw.c code
*/
@@ -97,43 +25,27 @@ nouveau_clock(void *obj)
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_CLOCK];
}
-struct nouveau_clocks {
- enum nv_clk_src name;
- u8 bios; /* 0xff for none */
-#define NVKM_CLK_DOM_FLAG_CORE 0x01
- u8 flags;
- const char *mname;
- int mdiv;
-};
-
-#define nouveau_clock_create(p,e,o,i,d) \
- nouveau_clock_create_((p), (e), (o), (i), sizeof(**d), (void **)d)
-#define nouveau_clock_destroy(p) ({ \
- struct nouveau_clock *clk = (p); \
- _nouveau_clock_dtor(nv_object(clk)); \
-})
-#define nouveau_clock_init(p) ({ \
- struct nouveau_clock *clk = (p); \
- _nouveau_clock_init(nv_object(clk)); \
-})
+#define nouveau_clock_create(p,e,o,d) \
+ nouveau_subdev_create((p), (e), (o), 0, "CLOCK", "clock", d)
+#define nouveau_clock_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_clock_init(p) \
+ nouveau_subdev_init(&(p)->base)
#define nouveau_clock_fini(p,s) \
nouveau_subdev_fini(&(p)->base, (s))
int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *,
- struct nouveau_clocks *, int, void **);
-void _nouveau_clock_dtor(struct nouveau_object *);
-int _nouveau_clock_init(struct nouveau_object *);
+ struct nouveau_oclass *, void *, u32, int, void **);
+
+#define _nouveau_clock_dtor _nouveau_subdev_dtor
+#define _nouveau_clock_init _nouveau_subdev_init
#define _nouveau_clock_fini _nouveau_subdev_fini
extern struct nouveau_oclass nv04_clock_oclass;
extern struct nouveau_oclass nv40_clock_oclass;
-extern struct nouveau_oclass *nv50_clock_oclass;
-extern struct nouveau_oclass *nv84_clock_oclass;
-extern struct nouveau_oclass *nvaa_clock_oclass;
+extern struct nouveau_oclass nv50_clock_oclass;
extern struct nouveau_oclass nva3_clock_oclass;
extern struct nouveau_oclass nvc0_clock_oclass;
-extern struct nouveau_oclass nve0_clock_oclass;
int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq);
int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
@@ -143,9 +55,4 @@ int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
int clk, struct nouveau_pll_vals *);
-int nouveau_clock_ustate(struct nouveau_clock *, int req);
-int nouveau_clock_astate(struct nouveau_clock *, int req, int rel);
-int nouveau_clock_dstate(struct nouveau_clock *, int req, int rel);
-int nouveau_clock_tstate(struct nouveau_clock *, int req, int rel);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
index 8541aa3..2e74050 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -78,28 +78,23 @@ nouveau_fb(void *obj)
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
}
-extern struct nouveau_oclass *nv04_fb_oclass;
-extern struct nouveau_oclass *nv10_fb_oclass;
-extern struct nouveau_oclass *nv1a_fb_oclass;
-extern struct nouveau_oclass *nv20_fb_oclass;
-extern struct nouveau_oclass *nv25_fb_oclass;
-extern struct nouveau_oclass *nv30_fb_oclass;
-extern struct nouveau_oclass *nv35_fb_oclass;
-extern struct nouveau_oclass *nv36_fb_oclass;
-extern struct nouveau_oclass *nv40_fb_oclass;
-extern struct nouveau_oclass *nv41_fb_oclass;
-extern struct nouveau_oclass *nv44_fb_oclass;
-extern struct nouveau_oclass *nv46_fb_oclass;
-extern struct nouveau_oclass *nv47_fb_oclass;
-extern struct nouveau_oclass *nv49_fb_oclass;
-extern struct nouveau_oclass *nv4e_fb_oclass;
-extern struct nouveau_oclass *nv50_fb_oclass;
-extern struct nouveau_oclass *nv84_fb_oclass;
-extern struct nouveau_oclass *nva3_fb_oclass;
-extern struct nouveau_oclass *nvaa_fb_oclass;
-extern struct nouveau_oclass *nvaf_fb_oclass;
-extern struct nouveau_oclass *nvc0_fb_oclass;
-extern struct nouveau_oclass *nve0_fb_oclass;
+extern struct nouveau_oclass nv04_fb_oclass;
+extern struct nouveau_oclass nv10_fb_oclass;
+extern struct nouveau_oclass nv1a_fb_oclass;
+extern struct nouveau_oclass nv20_fb_oclass;
+extern struct nouveau_oclass nv25_fb_oclass;
+extern struct nouveau_oclass nv30_fb_oclass;
+extern struct nouveau_oclass nv35_fb_oclass;
+extern struct nouveau_oclass nv36_fb_oclass;
+extern struct nouveau_oclass nv40_fb_oclass;
+extern struct nouveau_oclass nv41_fb_oclass;
+extern struct nouveau_oclass nv44_fb_oclass;
+extern struct nouveau_oclass nv46_fb_oclass;
+extern struct nouveau_oclass nv47_fb_oclass;
+extern struct nouveau_oclass nv49_fb_oclass;
+extern struct nouveau_oclass nv4e_fb_oclass;
+extern struct nouveau_oclass nv50_fb_oclass;
+extern struct nouveau_oclass nvc0_fb_oclass;
struct nouveau_ram {
struct nouveau_object base;
@@ -126,17 +121,6 @@ struct nouveau_ram {
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 **);
-
- int (*calc)(struct nouveau_fb *, u32 freq);
- int (*prog)(struct nouveau_fb *);
- void (*tidy)(struct nouveau_fb *);
- struct {
- u8 version;
- u32 data;
- u8 size;
- } rammap, ramcfg, timing;
- u32 freq;
- u32 mr[16];
};
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
index 9fa5da7..7e4e277 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
@@ -60,18 +60,13 @@ void _nouveau_i2c_port_dtor(struct nouveau_object *);
#define _nouveau_i2c_port_init nouveau_object_init
#define _nouveau_i2c_port_fini nouveau_object_fini
-struct nouveau_i2c_board_info {
- struct i2c_board_info dev;
- u8 udelay; /* set to 0 to use the standard delay */
-};
-
struct nouveau_i2c {
struct nouveau_subdev base;
struct nouveau_i2c_port *(*find)(struct nouveau_i2c *, u8 index);
struct nouveau_i2c_port *(*find_type)(struct nouveau_i2c *, u16 type);
int (*identify)(struct nouveau_i2c *, int index,
- const char *what, struct nouveau_i2c_board_info *,
+ const char *what, struct i2c_board_info *,
bool (*match)(struct nouveau_i2c_port *,
struct i2c_board_info *));
struct list_head ports;
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
index adc88b7..ce6569f 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
@@ -11,6 +11,7 @@ struct nouveau_mc_intr {
struct nouveau_mc {
struct nouveau_subdev base;
+ const struct nouveau_mc_intr *intr_map;
bool use_msi;
};
@@ -20,8 +21,8 @@ nouveau_mc(void *obj)
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
}
-#define nouveau_mc_create(p,e,o,d) \
- nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_mc_create(p,e,o,m,d) \
+ nouveau_mc_create_((p), (e), (o), (m), sizeof(**d), (void **)d)
#define nouveau_mc_destroy(p) ({ \
struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
})
@@ -33,24 +34,20 @@ nouveau_mc(void *obj)
})
int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
+ struct nouveau_oclass *, const struct nouveau_mc_intr *,
+ int, void **);
void _nouveau_mc_dtor(struct nouveau_object *);
int _nouveau_mc_init(struct nouveau_object *);
int _nouveau_mc_fini(struct nouveau_object *, bool);
-struct nouveau_mc_oclass {
- struct nouveau_oclass base;
- const struct nouveau_mc_intr *intr;
- void (*msi_rearm)(struct nouveau_mc *);
-};
+extern struct nouveau_oclass nv04_mc_oclass;
+extern struct nouveau_oclass nv44_mc_oclass;
+extern struct nouveau_oclass nv50_mc_oclass;
+extern struct nouveau_oclass nv98_mc_oclass;
+extern struct nouveau_oclass nvc0_mc_oclass;
-extern struct nouveau_oclass *nv04_mc_oclass;
-extern struct nouveau_oclass *nv40_mc_oclass;
-extern struct nouveau_oclass *nv44_mc_oclass;
-extern struct nouveau_oclass *nv50_mc_oclass;
-extern struct nouveau_oclass *nv94_mc_oclass;
-extern struct nouveau_oclass *nv98_mc_oclass;
-extern struct nouveau_oclass *nvc0_mc_oclass;
-extern struct nouveau_oclass *nvc3_mc_oclass;
+extern const struct nouveau_mc_intr nv04_mc_intr[];
+int nv04_mc_init(struct nouveau_object *);
+int nv50_mc_init(struct nouveau_object *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
deleted file mode 100644
index c5c92cb..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef __NOUVEAU_PWR_H__
-#define __NOUVEAU_PWR_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_pwr {
- struct nouveau_subdev base;
-
- struct {
- u32 limit;
- u32 *data;
- u32 size;
- } code;
-
- struct {
- u32 limit;
- u32 *data;
- u32 size;
- } data;
-
- struct {
- u32 base;
- u32 size;
- } send;
-
- struct {
- u32 base;
- u32 size;
-
- struct work_struct work;
- wait_queue_head_t wait;
- u32 process;
- u32 message;
- u32 data[2];
- } recv;
-
- int (*message)(struct nouveau_pwr *, u32[2], u32, u32, u32, u32);
-};
-
-static inline struct nouveau_pwr *
-nouveau_pwr(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_PWR];
-}
-
-#define nouveau_pwr_create(p, e, o, d) \
- nouveau_pwr_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_pwr_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_pwr_init(p) ({ \
- struct nouveau_pwr *ppwr = (p); \
- _nouveau_pwr_init(nv_object(ppwr)); \
-})
-#define nouveau_pwr_fini(p,s) ({ \
- struct nouveau_pwr *ppwr = (p); \
- _nouveau_pwr_fini(nv_object(ppwr), (s)); \
-})
-
-int nouveau_pwr_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-#define _nouveau_pwr_dtor _nouveau_subdev_dtor
-int _nouveau_pwr_init(struct nouveau_object *);
-int _nouveau_pwr_fini(struct nouveau_object *, bool);
-
-extern struct nouveau_oclass nva3_pwr_oclass;
-extern struct nouveau_oclass nvc0_pwr_oclass;
-extern struct nouveau_oclass nvd0_pwr_oclass;
-extern struct nouveau_oclass nv108_pwr_oclass;
-
-/* interface to MEMX process running on PPWR */
-struct nouveau_memx;
-int nouveau_memx_init(struct nouveau_pwr *, struct nouveau_memx **);
-int nouveau_memx_fini(struct nouveau_memx **, bool exec);
-void nouveau_memx_wr32(struct nouveau_memx *, u32 addr, u32 data);
-void nouveau_memx_wait(struct nouveau_memx *,
- u32 addr, u32 mask, u32 data, u32 nsec);
-void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
index 69891d4..c075998 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
@@ -71,8 +71,6 @@ void _nouveau_therm_dtor(struct nouveau_object *);
int _nouveau_therm_init(struct nouveau_object *);
int _nouveau_therm_fini(struct nouveau_object *, bool);
-int nouveau_therm_cstate(struct nouveau_therm *, int, int);
-
extern struct nouveau_oclass nv40_therm_oclass;
extern struct nouveau_oclass nv50_therm_oclass;
extern struct nouveau_oclass nv84_therm_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h b/drivers/gpu/drm/nouveau/core/include/subdev/volt.h
deleted file mode 100644
index 820b62f..0000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __NOUVEAU_VOLT_H__
-#define __NOUVEAU_VOLT_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_voltage {
- u32 uv;
- u8 id;
-};
-
-struct nouveau_volt {
- struct nouveau_subdev base;
-
- int (*vid_get)(struct nouveau_volt *);
- int (*get)(struct nouveau_volt *);
- int (*vid_set)(struct nouveau_volt *, u8 vid);
- int (*set)(struct nouveau_volt *, u32 uv);
- int (*set_id)(struct nouveau_volt *, u8 id, int condition);
-
- u8 vid_mask;
- u8 vid_nr;
- struct {
- u32 uv;
- u8 vid;
- } vid[256];
-};
-
-static inline struct nouveau_volt *
-nouveau_volt(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VOLT];
-}
-
-#define nouveau_volt_create(p, e, o, d) \
- nouveau_volt_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_volt_destroy(p) ({ \
- struct nouveau_volt *v = (p); \
- _nouveau_volt_dtor(nv_object(v)); \
-})
-#define nouveau_volt_init(p) ({ \
- struct nouveau_volt *v = (p); \
- _nouveau_volt_init(nv_object(v)); \
-})
-#define nouveau_volt_fini(p,s) \
- nouveau_subdev_fini((p), (s))
-
-int nouveau_volt_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_volt_dtor(struct nouveau_object *);
-int _nouveau_volt_init(struct nouveau_object *);
-#define _nouveau_volt_fini _nouveau_subdev_fini
-
-extern struct nouveau_oclass nv40_volt_oclass;
-
-int nouveau_voltgpio_init(struct nouveau_volt *);
-int nouveau_voltgpio_get(struct nouveau_volt *);
-int nouveau_voltgpio_set(struct nouveau_volt *, u8);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c b/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c
deleted file mode 100644
index c1835e5..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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/bios/bit.h>
-#include <subdev/bios/boost.h>
-
-u16
-nvbios_boostTe(struct nouveau_bios *bios,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
-{
- struct bit_entry bit_P;
- u16 boost = 0x0000;
-
- if (!bit_entry(bios, 'P', &bit_P)) {
- if (bit_P.version == 2)
- boost = nv_ro16(bios, bit_P.offset + 0x30);
-
- if (boost) {
- *ver = nv_ro08(bios, boost + 0);
- switch (*ver) {
- case 0x11:
- *hdr = nv_ro08(bios, boost + 1);
- *cnt = nv_ro08(bios, boost + 5);
- *len = nv_ro08(bios, boost + 2);
- *snr = nv_ro08(bios, boost + 4);
- *ssz = nv_ro08(bios, boost + 3);
- return boost;
- default:
- break;
- }
- }
- }
-
- return 0x0000;
-}
-
-u16
-nvbios_boostEe(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
- u8 snr, ssz;
- u16 data = nvbios_boostTe(bios, ver, hdr, cnt, len, &snr, &ssz);
- if (data && idx < *cnt) {
- data = data + *hdr + (idx * (*len + (snr * ssz)));
- *hdr = *len;
- *cnt = snr;
- *len = ssz;
- return data;
- }
- return 0x0000;
-}
-
-u16
-nvbios_boostEp(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info)
-{
- u16 data = nvbios_boostEe(bios, idx, ver, hdr, cnt, len);
- memset(info, 0x00, sizeof(*info));
- if (data) {
- info->pstate = (nv_ro16(bios, data + 0x00) & 0x01e0) >> 5;
- info->min = nv_ro16(bios, data + 0x02) * 1000;
- info->max = nv_ro16(bios, data + 0x04) * 1000;
- }
- return data;
-}
-
-u16
-nvbios_boostEm(struct nouveau_bios *bios, u8 pstate,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info)
-{
- u32 data, idx = 0;
- while ((data = nvbios_boostEp(bios, idx++, ver, hdr, cnt, len, info))) {
- if (info->pstate == pstate)
- break;
- }
- return data;
-}
-
-u16
-nvbios_boostSe(struct nouveau_bios *bios, int idx,
- u16 data, u8 *ver, u8 *hdr, u8 cnt, u8 len)
-{
- if (data && idx < cnt) {
- data = data + *hdr + (idx * len);
- *hdr = len;
- return data;
- }
- return 0x0000;
-}
-
-u16
-nvbios_boostSp(struct nouveau_bios *bios, int idx,
- u16 data, u8 *ver, u8 *hdr, u8 cnt, u8 len,
- struct nvbios_boostS *info)
-{
- data = nvbios_boostSe(bios, idx, data, ver, hdr, cnt, len);
- memset(info, 0x00, sizeof(*info));
- if (data) {
- info->domain = nv_ro08(bios, data + 0x00);
- info->percent = nv_ro08(bios, data + 0x01);
- info->min = nv_ro16(bios, data + 0x02) * 1000;
- info->max = nv_ro16(bios, data + 0x04) * 1000;
- }
- return data;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c b/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c
deleted file mode 100644
index d3b1532..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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/bios/bit.h>
-#include <subdev/bios/cstep.h>
-
-u16
-nvbios_cstepTe(struct nouveau_bios *bios,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz)
-{
- struct bit_entry bit_P;
- u16 cstep = 0x0000;
-
- if (!bit_entry(bios, 'P', &bit_P)) {
- if (bit_P.version == 2)
- cstep = nv_ro16(bios, bit_P.offset + 0x34);
-
- if (cstep) {
- *ver = nv_ro08(bios, cstep + 0);
- switch (*ver) {
- case 0x10:
- *hdr = nv_ro08(bios, cstep + 1);
- *cnt = nv_ro08(bios, cstep + 3);
- *len = nv_ro08(bios, cstep + 2);
- *xnr = nv_ro08(bios, cstep + 5);
- *xsz = nv_ro08(bios, cstep + 4);
- return cstep;
- default:
- break;
- }
- }
- }
-
- return 0x0000;
-}
-
-u16
-nvbios_cstepEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
-{
- u8 cnt, len, xnr, xsz;
- u16 data = nvbios_cstepTe(bios, ver, hdr, &cnt, &len, &xnr, &xsz);
- if (data && idx < cnt) {
- data = data + *hdr + (idx * len);
- *hdr = len;
- return data;
- }
- return 0x0000;
-}
-
-u16
-nvbios_cstepEp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
- struct nvbios_cstepE *info)
-{
- u16 data = nvbios_cstepEe(bios, idx, ver, hdr);
- memset(info, 0x00, sizeof(*info));
- if (data) {
- info->pstate = (nv_ro16(bios, data + 0x00) & 0x01e0) >> 5;
- info->index = nv_ro08(bios, data + 0x03);
- }
- return data;
-}
-
-u16
-nvbios_cstepEm(struct nouveau_bios *bios, u8 pstate, u8 *ver, u8 *hdr,
- struct nvbios_cstepE *info)
-{
- u32 data, idx = 0;
- while ((data = nvbios_cstepEp(bios, idx++, ver, hdr, info))) {
- if (info->pstate == pstate)
- break;
- }
- return data;
-}
-
-u16
-nvbios_cstepXe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
-{
- u8 cnt, len, xnr, xsz;
- u16 data = nvbios_cstepTe(bios, ver, hdr, &cnt, &len, &xnr, &xsz);
- if (data && idx < xnr) {
- data = data + *hdr + (cnt * len) + (idx * xsz);
- *hdr = xsz;
- return data;
- }
- return 0x0000;
-}
-
-u16
-nvbios_cstepXp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
- struct nvbios_cstepX *info)
-{
- u16 data = nvbios_cstepXe(bios, idx, ver, hdr);
- memset(info, 0x00, sizeof(*info));
- if (data) {
- info->freq = nv_ro16(bios, data + 0x00) * 1000;
- info->unkn[0] = nv_ro08(bios, data + 0x02);
- info->unkn[1] = nv_ro08(bios, data + 0x03);
- info->voltage = nv_ro08(bios, data + 0x04);
- }
- return data;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
index 7628fe7..663853b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
@@ -89,7 +89,6 @@ nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx,
struct nvbios_dpout *info)
{
u16 data = nvbios_dpout_entry(bios, idx, ver, hdr, cnt, len);
- memset(info, 0x00, sizeof(*info));
if (data && *ver) {
info->type = nv_ro16(bios, data + 0x00);
info->mask = nv_ro16(bios, data + 0x02);
@@ -100,12 +99,9 @@ nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx,
info->script[0] = nv_ro16(bios, data + 0x06);
info->script[1] = nv_ro16(bios, data + 0x08);
info->lnkcmp = nv_ro16(bios, data + 0x0a);
- if (*len >= 0x0f) {
- info->script[2] = nv_ro16(bios, data + 0x0c);
- info->script[3] = nv_ro16(bios, data + 0x0e);
- }
- if (*len >= 0x11)
- info->script[4] = nv_ro16(bios, data + 0x10);
+ info->script[2] = nv_ro16(bios, data + 0x0c);
+ info->script[3] = nv_ro16(bios, data + 0x0e);
+ info->script[4] = nv_ro16(bios, data + 0x10);
break;
case 0x40:
info->flags = nv_ro08(bios, data + 0x04);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index 420908c..57cda2a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -2180,7 +2180,7 @@ nvbios_init(struct nouveau_subdev *subdev, bool execute)
u16 data;
if (execute)
- nv_info(bios, "running init tables\n");
+ nv_suspend(bios, "running init tables\n");
while (!ret && (data = (init_script(bios, ++i)))) {
struct nvbios_init init = {
.subdev = subdev,
@@ -2210,5 +2210,5 @@ nvbios_init(struct nouveau_subdev *subdev, bool execute)
ret = nvbios_exec(&init);
}
- return ret;
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c
index 675e221..bcbb056 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c
@@ -26,9 +26,8 @@
#include <subdev/bios/bit.h>
#include <subdev/bios/perf.h>
-u16
-nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
- u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
+static u16
+perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_P;
u16 perf = 0x0000;
@@ -39,22 +38,10 @@ nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
if (perf) {
*ver = nv_ro08(bios, perf + 0);
*hdr = nv_ro08(bios, perf + 1);
- if (*ver >= 0x40 && *ver < 0x41) {
- *cnt = nv_ro08(bios, perf + 5);
- *len = nv_ro08(bios, perf + 2);
- *snr = nv_ro08(bios, perf + 4);
- *ssz = nv_ro08(bios, perf + 3);
- return perf;
- } else
- if (*ver >= 0x20 && *ver < 0x40) {
- *cnt = nv_ro08(bios, perf + 2);
- *len = nv_ro08(bios, perf + 3);
- *snr = nv_ro08(bios, perf + 4);
- *ssz = nv_ro08(bios, perf + 5);
- return perf;
- }
}
- }
+ } else
+ nv_error(bios, "unknown offset for perf in BIT P %d\n",
+ bit_P.version);
}
if (bios->bmp_offset) {
@@ -63,132 +50,19 @@ nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
if (perf) {
*hdr = nv_ro08(bios, perf + 0);
*ver = nv_ro08(bios, perf + 1);
- *cnt = nv_ro08(bios, perf + 2);
- *len = nv_ro08(bios, perf + 3);
- *snr = 0;
- *ssz = 0;
- return perf;
}
}
}
- return 0x0000;
-}
-
-u16
-nvbios_perf_entry(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
- u8 snr, ssz;
- u16 perf = nvbios_perf_table(bios, ver, hdr, cnt, len, &snr, &ssz);
- if (perf && idx < *cnt) {
- perf = perf + *hdr + (idx * (*len + (snr * ssz)));
- *hdr = *len;
- *cnt = snr;
- *len = ssz;
- return perf;
- }
- return 0x0000;
-}
-
-u16
-nvbios_perfEp(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_perfE *info)
-{
- u16 perf = nvbios_perf_entry(bios, idx, ver, hdr, cnt, len);
- memset(info, 0x00, sizeof(*info));
- info->pstate = nv_ro08(bios, perf + 0x00);
- switch (!!perf * *ver) {
- case 0x12:
- case 0x13:
- case 0x14:
- info->core = nv_ro32(bios, perf + 0x01) * 10;
- info->memory = nv_ro32(bios, perf + 0x05) * 20;
- info->fanspeed = nv_ro08(bios, perf + 0x37);
- if (*hdr > 0x38)
- info->voltage = nv_ro08(bios, perf + 0x38);
- break;
- case 0x21:
- case 0x23:
- case 0x24:
- info->fanspeed = nv_ro08(bios, perf + 0x04);
- info->voltage = nv_ro08(bios, perf + 0x05);
- info->shader = nv_ro16(bios, perf + 0x06) * 1000;
- info->core = info->shader + (signed char)
- nv_ro08(bios, perf + 0x08) * 1000;
- switch (nv_device(bios)->chipset) {
- case 0x49:
- case 0x4b:
- info->memory = nv_ro16(bios, perf + 0x0b) * 1000;
- break;
- default:
- info->memory = nv_ro16(bios, perf + 0x0b) * 2000;
- break;
- }
- break;
- case 0x25:
- info->fanspeed = nv_ro08(bios, perf + 0x04);
- info->voltage = nv_ro08(bios, perf + 0x05);
- info->core = nv_ro16(bios, perf + 0x06) * 1000;
- info->shader = nv_ro16(bios, perf + 0x0a) * 1000;
- info->memory = nv_ro16(bios, perf + 0x0c) * 1000;
- break;
- case 0x30:
- info->script = nv_ro16(bios, perf + 0x02);
- case 0x35:
- info->fanspeed = nv_ro08(bios, perf + 0x06);
- info->voltage = nv_ro08(bios, perf + 0x07);
- info->core = nv_ro16(bios, perf + 0x08) * 1000;
- info->shader = nv_ro16(bios, perf + 0x0a) * 1000;
- info->memory = nv_ro16(bios, perf + 0x0c) * 1000;
- info->vdec = nv_ro16(bios, perf + 0x10) * 1000;
- info->disp = nv_ro16(bios, perf + 0x14) * 1000;
- break;
- case 0x40:
- info->voltage = nv_ro08(bios, perf + 0x02);
- break;
- default:
- return 0x0000;
- }
return perf;
}
-u32
-nvbios_perfSe(struct nouveau_bios *bios, u32 perfE, int idx,
- u8 *ver, u8 *hdr, u8 cnt, u8 len)
-{
- u32 data = 0x00000000;
- if (idx < cnt) {
- data = perfE + *hdr + (idx * len);
- *hdr = len;
- }
- return data;
-}
-
-u32
-nvbios_perfSp(struct nouveau_bios *bios, u32 perfE, int idx,
- u8 *ver, u8 *hdr, u8 cnt, u8 len,
- struct nvbios_perfS *info)
-{
- u32 data = nvbios_perfSe(bios, perfE, idx, ver, hdr, cnt, len);
- memset(info, 0x00, sizeof(*info));
- switch (!!data * *ver) {
- case 0x40:
- info->v40.freq = (nv_ro16(bios, data + 0x00) & 0x3fff) * 1000;
- break;
- default:
- break;
- }
- return data;
-}
-
int
nvbios_perf_fan_parse(struct nouveau_bios *bios,
struct nvbios_perf_fan *fan)
{
- u8 ver, hdr, cnt, len, snr, ssz;
- u16 perf = nvbios_perf_table(bios, &ver, &hdr, &cnt, &len, &snr, &ssz);
+ u8 ver = 0, hdr = 0, cnt = 0, len = 0;
+ u16 perf = perf_table(bios, &ver, &hdr, &cnt, &len);
if (!perf)
return -ENODEV;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
index 1f76de5..f835501 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
@@ -114,7 +114,6 @@ pll_map(struct nouveau_bios *bios)
switch (nv_device(bios)->card_type) {
case NV_04:
case NV_10:
- case NV_11:
case NV_20:
case NV_30:
return nv04_pll_mapping;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c
deleted file mode 100644
index 916fa9d..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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/bios/bit.h>
-#include <subdev/bios/rammap.h>
-
-u16
-nvbios_rammap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
- u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
-{
- struct bit_entry bit_P;
- u16 rammap = 0x0000;
-
- if (!bit_entry(bios, 'P', &bit_P)) {
- if (bit_P.version == 2)
- rammap = nv_ro16(bios, bit_P.offset + 4);
-
- if (rammap) {
- *ver = nv_ro08(bios, rammap + 0);
- switch (*ver) {
- case 0x10:
- case 0x11:
- *hdr = nv_ro08(bios, rammap + 1);
- *cnt = nv_ro08(bios, rammap + 5);
- *len = nv_ro08(bios, rammap + 2);
- *snr = nv_ro08(bios, rammap + 4);
- *ssz = nv_ro08(bios, rammap + 3);
- return rammap;
- default:
- break;
- }
- }
- }
-
- return 0x0000;
-}
-
-u16
-nvbios_rammap_entry(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
- u8 snr, ssz;
- u16 rammap = nvbios_rammap_table(bios, ver, hdr, cnt, len, &snr, &ssz);
- if (rammap && idx < *cnt) {
- rammap = rammap + *hdr + (idx * (*len + (snr * ssz)));
- *hdr = *len;
- *cnt = snr;
- *len = ssz;
- return rammap;
- }
- return 0x0000;
-}
-
-u16
-nvbios_rammap_match(struct nouveau_bios *bios, u16 khz,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
- int idx = 0;
- u32 data;
- while ((data = nvbios_rammap_entry(bios, idx++, ver, hdr, cnt, len))) {
- if (khz >= nv_ro16(bios, data + 0x00) &&
- khz <= nv_ro16(bios, data + 0x02))
- break;
- }
- return data;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c
deleted file mode 100644
index 151c2d6..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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/bios/bit.h>
-#include <subdev/bios/timing.h>
-
-u16
-nvbios_timing_table(struct nouveau_bios *bios,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
- struct bit_entry bit_P;
- u16 timing = 0x0000;
-
- if (!bit_entry(bios, 'P', &bit_P)) {
- if (bit_P.version == 1)
- timing = nv_ro16(bios, bit_P.offset + 4);
- else
- if (bit_P.version == 2)
- timing = nv_ro16(bios, bit_P.offset + 8);
-
- if (timing) {
- *ver = nv_ro08(bios, timing + 0);
- switch (*ver) {
- case 0x10:
- *hdr = nv_ro08(bios, timing + 1);
- *cnt = nv_ro08(bios, timing + 2);
- *len = nv_ro08(bios, timing + 3);
- return timing;
- case 0x20:
- *hdr = nv_ro08(bios, timing + 1);
- *cnt = nv_ro08(bios, timing + 3);
- *len = nv_ro08(bios, timing + 2);
- return timing;
- default:
- break;
- }
- }
- }
-
- return 0x0000;
-}
-
-u16
-nvbios_timing_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
-{
- u8 hdr, cnt;
- u16 timing = nvbios_timing_table(bios, ver, &hdr, &cnt, len);
- if (timing && idx < cnt)
- return timing + hdr + (idx * *len);
- return 0x0000;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c b/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c
deleted file mode 100644
index f343a1b..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2012 Nouveau Community
- *
- * 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: Martin Peres
- */
-
-#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/vmap.h>
-
-u16
-nvbios_vmap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
- struct bit_entry bit_P;
- u16 vmap = 0x0000;
-
- if (!bit_entry(bios, 'P', &bit_P)) {
- if (bit_P.version == 2) {
- vmap = nv_ro16(bios, bit_P.offset + 0x20);
- if (vmap) {
- *ver = nv_ro08(bios, vmap + 0);
- switch (*ver) {
- case 0x10:
- case 0x20:
- *hdr = nv_ro08(bios, vmap + 1);
- *cnt = nv_ro08(bios, vmap + 3);
- *len = nv_ro08(bios, vmap + 2);
- return vmap;
- default:
- break;
- }
- }
- }
- }
-
- return 0x0000;
-}
-
-u16
-nvbios_vmap_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_vmap *info)
-{
- u16 vmap = nvbios_vmap_table(bios, ver, hdr, cnt, len);
- memset(info, 0x00, sizeof(*info));
- switch (!!vmap * *ver) {
- case 0x10:
- case 0x20:
- break;
- }
- return vmap;
-}
-
-u16
-nvbios_vmap_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
-{
- u8 hdr, cnt;
- u16 vmap = nvbios_vmap_table(bios, ver, &hdr, &cnt, len);
- if (vmap && idx < cnt) {
- vmap = vmap + hdr + (idx * *len);
- return vmap;
- }
- return 0x0000;
-}
-
-u16
-nvbios_vmap_entry_parse(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len,
- struct nvbios_vmap_entry *info)
-{
- u16 vmap = nvbios_vmap_entry(bios, idx, ver, len);
- memset(info, 0x00, sizeof(*info));
- switch (!!vmap * *ver) {
- case 0x10:
- info->link = 0xff;
- info->min = nv_ro32(bios, vmap + 0x00);
- info->max = nv_ro32(bios, vmap + 0x04);
- info->arg[0] = nv_ro32(bios, vmap + 0x08);
- info->arg[1] = nv_ro32(bios, vmap + 0x0c);
- info->arg[2] = nv_ro32(bios, vmap + 0x10);
- break;
- case 0x20:
- info->unk0 = nv_ro08(bios, vmap + 0x00);
- info->link = nv_ro08(bios, vmap + 0x01);
- info->min = nv_ro32(bios, vmap + 0x02);
- info->max = nv_ro32(bios, vmap + 0x06);
- info->arg[0] = nv_ro32(bios, vmap + 0x0a);
- info->arg[1] = nv_ro32(bios, vmap + 0x0e);
- info->arg[2] = nv_ro32(bios, vmap + 0x12);
- info->arg[3] = nv_ro32(bios, vmap + 0x16);
- info->arg[4] = nv_ro32(bios, vmap + 0x1a);
- info->arg[5] = nv_ro32(bios, vmap + 0x1e);
- break;
- }
- return vmap;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c b/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c
deleted file mode 100644
index bb590de..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2012 Nouveau Community
- *
- * 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: Martin Peres
- */
-
-#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/volt.h>
-
-u16
-nvbios_volt_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
- struct bit_entry bit_P;
- u16 volt = 0x0000;
-
- if (!bit_entry(bios, 'P', &bit_P)) {
- if (bit_P.version == 2)
- volt = nv_ro16(bios, bit_P.offset + 0x0c);
- else
- if (bit_P.version == 1)
- volt = nv_ro16(bios, bit_P.offset + 0x10);
-
- if (volt) {
- *ver = nv_ro08(bios, volt + 0);
- switch (*ver) {
- case 0x12:
- *hdr = 5;
- *cnt = nv_ro08(bios, volt + 2);
- *len = nv_ro08(bios, volt + 1);
- return volt;
- case 0x20:
- *hdr = nv_ro08(bios, volt + 1);
- *cnt = nv_ro08(bios, volt + 2);
- *len = nv_ro08(bios, volt + 3);
- return volt;
- case 0x30:
- case 0x40:
- case 0x50:
- *hdr = nv_ro08(bios, volt + 1);
- *cnt = nv_ro08(bios, volt + 3);
- *len = nv_ro08(bios, volt + 2);
- return volt;
- }
- }
- }
-
- return 0x0000;
-}
-
-u16
-nvbios_volt_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_volt *info)
-{
- u16 volt = nvbios_volt_table(bios, ver, hdr, cnt, len);
- memset(info, 0x00, sizeof(*info));
- switch (!!volt * *ver) {
- case 0x12:
- info->vidmask = nv_ro08(bios, volt + 0x04);
- break;
- case 0x20:
- info->vidmask = nv_ro08(bios, volt + 0x05);
- break;
- case 0x30:
- info->vidmask = nv_ro08(bios, volt + 0x04);
- break;
- case 0x40:
- info->base = nv_ro32(bios, volt + 0x04);
- info->step = nv_ro16(bios, volt + 0x08);
- info->vidmask = nv_ro08(bios, volt + 0x0b);
- /*XXX*/
- info->min = 0;
- info->max = info->base;
- break;
- case 0x50:
- info->vidmask = nv_ro08(bios, volt + 0x06);
- info->min = nv_ro32(bios, volt + 0x0a);
- info->max = nv_ro32(bios, volt + 0x0e);
- info->base = nv_ro32(bios, volt + 0x12) & 0x00ffffff;
- info->step = nv_ro16(bios, volt + 0x16);
- break;
- }
- return volt;
-}
-
-u16
-nvbios_volt_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
-{
- u8 hdr, cnt;
- u16 volt = nvbios_volt_table(bios, ver, &hdr, &cnt, len);
- if (volt && idx < cnt) {
- volt = volt + hdr + (idx * *len);
- return volt;
- }
- return 0x0000;
-}
-
-u16
-nvbios_volt_entry_parse(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len,
- struct nvbios_volt_entry *info)
-{
- u16 volt = nvbios_volt_entry(bios, idx, ver, len);
- memset(info, 0x00, sizeof(*info));
- switch (!!volt * *ver) {
- case 0x12:
- case 0x20:
- info->voltage = nv_ro08(bios, volt + 0x00) * 10000;
- info->vid = nv_ro08(bios, volt + 0x01);
- break;
- case 0x30:
- info->voltage = nv_ro08(bios, volt + 0x00) * 10000;
- info->vid = nv_ro08(bios, volt + 0x01) >> 2;
- break;
- case 0x40:
- case 0x50:
- break;
- }
- return volt;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c b/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c
deleted file mode 100644
index f757470..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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 <bskeggs@redhat.com>
- */
-
-#include <subdev/timer.h>
-#include <subdev/bus.h>
-
-struct nouveau_hwsq {
- struct nouveau_bus *pbus;
- u32 addr;
- u32 data;
- struct {
- u8 data[512];
- u8 size;
- } c;
-};
-
-static void
-hwsq_cmd(struct nouveau_hwsq *hwsq, int size, u8 data[])
-{
- memcpy(&hwsq->c.data[hwsq->c.size], data, size * sizeof(data[0]));
- hwsq->c.size += size;
-}
-
-int
-nouveau_hwsq_init(struct nouveau_bus *pbus, struct nouveau_hwsq **phwsq)
-{
- struct nouveau_hwsq *hwsq;
-
- hwsq = *phwsq = kmalloc(sizeof(*hwsq), GFP_KERNEL);
- if (hwsq) {
- hwsq->pbus = pbus;
- hwsq->addr = ~0;
- hwsq->data = ~0;
- memset(hwsq->c.data, 0x7f, sizeof(hwsq->c.data));
- hwsq->c.size = 0;
- }
-
- return hwsq ? 0 : -ENOMEM;
-}
-
-int
-nouveau_hwsq_fini(struct nouveau_hwsq **phwsq, bool exec)
-{
- struct nouveau_hwsq *hwsq = *phwsq;
- int ret = 0, i;
- if (hwsq) {
- struct nouveau_bus *pbus = hwsq->pbus;
- hwsq->c.size = (hwsq->c.size + 4) / 4;
- if (hwsq->c.size <= pbus->hwsq_size) {
- if (exec)
- ret = pbus->hwsq_exec(pbus, (u32 *)hwsq->c.data,
- hwsq->c.size);
- if (ret)
- nv_error(pbus, "hwsq exec failed: %d\n", ret);
- } else {
- nv_error(pbus, "hwsq ucode too large\n");
- ret = -ENOSPC;
- }
-
- for (i = 0; ret && i < hwsq->c.size; i++)
- nv_error(pbus, "\t0x%08x\n", ((u32 *)hwsq->c.data)[i]);
-
- *phwsq = NULL;
- kfree(hwsq);
- }
- return ret;
-}
-
-void
-nouveau_hwsq_wr32(struct nouveau_hwsq *hwsq, u32 addr, u32 data)
-{
- nv_debug(hwsq->pbus, "R[%06x] = 0x%08x\n", addr, data);
-
- if (hwsq->data != data) {
- if ((data & 0xffff0000) != (hwsq->data & 0xffff0000)) {
- hwsq_cmd(hwsq, 5, (u8[]){ 0xe2, data, data >> 8,
- data >> 16, data >> 24 });
- } else {
- hwsq_cmd(hwsq, 3, (u8[]){ 0x42, data, data >> 8 });
- }
- }
-
- if ((addr & 0xffff0000) != (hwsq->addr & 0xffff0000)) {
- hwsq_cmd(hwsq, 5, (u8[]){ 0xe0, addr, addr >> 8,
- addr >> 16, addr >> 24 });
- } else {
- hwsq_cmd(hwsq, 3, (u8[]){ 0x40, addr, addr >> 8 });
- }
-
- hwsq->addr = addr;
- hwsq->data = data;
-}
-
-void
-nouveau_hwsq_setf(struct nouveau_hwsq *hwsq, u8 flag, int data)
-{
- nv_debug(hwsq->pbus, " FLAG[%02x] = %d\n", flag, data);
- flag += 0x80;
- if (data >= 0)
- flag += 0x20;
- if (data >= 1)
- flag += 0x20;
- hwsq_cmd(hwsq, 1, (u8[]){ flag });
-}
-
-void
-nouveau_hwsq_wait(struct nouveau_hwsq *hwsq, u8 flag, u8 data)
-{
- nv_debug(hwsq->pbus, " WAIT[%02x] = %d\n", flag, data);
- hwsq_cmd(hwsq, 3, (u8[]){ 0x5f, flag, data });
-}
-
-void
-nouveau_hwsq_nsec(struct nouveau_hwsq *hwsq, u32 nsec)
-{
- u8 shift = 0, usec = nsec / 1000;
- while (usec & ~3) {
- usec >>= 2;
- shift++;
- }
-
- nv_debug(hwsq->pbus, " DELAY = %d ns\n", nsec);
- hwsq_cmd(hwsq, 1, (u8[]){ 0x00 | (shift << 2) | usec });
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h b/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h
deleted file mode 100644
index 12176f9..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef __NVKM_BUS_HWSQ_H__
-#define __NVKM_BUS_HWSQ_H__
-
-#include <subdev/bus.h>
-
-struct hwsq {
- struct nouveau_subdev *subdev;
- struct nouveau_hwsq *hwsq;
- int sequence;
-};
-
-struct hwsq_reg {
- int sequence;
- bool force;
- u32 addr[2];
- u32 data;
-};
-
-static inline struct hwsq_reg
-hwsq_reg2(u32 addr1, u32 addr2)
-{
- return (struct hwsq_reg) {
- .sequence = 0,
- .force = 0,
- .addr = { addr1, addr2 },
- .data = 0xdeadbeef,
- };
-}
-
-static inline struct hwsq_reg
-hwsq_reg(u32 addr)
-{
- return hwsq_reg2(addr, addr);
-}
-
-static inline int
-hwsq_init(struct hwsq *ram, struct nouveau_subdev *subdev)
-{
- struct nouveau_bus *pbus = nouveau_bus(subdev);
- int ret;
-
- ret = nouveau_hwsq_init(pbus, &ram->hwsq);
- if (ret)
- return ret;
-
- ram->sequence++;
- ram->subdev = subdev;
- return 0;
-}
-
-static inline int
-hwsq_exec(struct hwsq *ram, bool exec)
-{
- int ret = 0;
- if (ram->subdev) {
- ret = nouveau_hwsq_fini(&ram->hwsq, exec);
- ram->subdev = NULL;
- }
- return ret;
-}
-
-static inline u32
-hwsq_rd32(struct hwsq *ram, struct hwsq_reg *reg)
-{
- if (reg->sequence != ram->sequence)
- reg->data = nv_rd32(ram->subdev, reg->addr[0]);
- return reg->data;
-}
-
-static inline void
-hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data)
-{
- reg->sequence = ram->sequence;
- reg->data = data;
- if (reg->addr[0] != reg->addr[1])
- nouveau_hwsq_wr32(ram->hwsq, reg->addr[1], reg->data);
- nouveau_hwsq_wr32(ram->hwsq, reg->addr[0], reg->data);
-}
-
-static inline void
-hwsq_nuke(struct hwsq *ram, struct hwsq_reg *reg)
-{
- reg->force = true;
-}
-
-static inline u32
-hwsq_mask(struct hwsq *ram, struct hwsq_reg *reg, u32 mask, u32 data)
-{
- u32 temp = hwsq_rd32(ram, reg);
- if (temp != ((temp & ~mask) | data) || reg->force)
- hwsq_wr32(ram, reg, (temp & ~mask) | data);
- return temp;
-}
-
-static inline void
-hwsq_setf(struct hwsq *ram, u8 flag, int data)
-{
- nouveau_hwsq_setf(ram->hwsq, flag, data);
-}
-
-static inline void
-hwsq_wait(struct hwsq *ram, u8 flag, u8 data)
-{
- nouveau_hwsq_wait(ram->hwsq, flag, data);
-}
-
-static inline void
-hwsq_nsec(struct hwsq *ram, u32 nsec)
-{
- nouveau_hwsq_nsec(ram->hwsq, nsec);
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c
index 23921b5..8c7f805 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c
@@ -23,7 +23,11 @@
* Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/bus.h>
+
+struct nv04_bus_priv {
+ struct nouveau_bus base;
+};
static void
nv04_bus_intr(struct nouveau_subdev *subdev)
@@ -52,22 +56,10 @@ nv04_bus_intr(struct nouveau_subdev *subdev)
}
static int
-nv04_bus_init(struct nouveau_object *object)
-{
- struct nv04_bus_priv *priv = (void *)object;
-
- nv_wr32(priv, 0x001100, 0xffffffff);
- nv_wr32(priv, 0x001140, 0x00000111);
-
- return nouveau_bus_init(&priv->base);
-}
-
-int
nv04_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv04_bus_impl *impl = (void *)oclass;
struct nv04_bus_priv *priv;
int ret;
@@ -76,20 +68,28 @@ nv04_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_subdev(priv)->intr = impl->intr;
- priv->base.hwsq_exec = impl->hwsq_exec;
- priv->base.hwsq_size = impl->hwsq_size;
+ nv_subdev(priv)->intr = nv04_bus_intr;
return 0;
}
-struct nouveau_oclass *
-nv04_bus_oclass = &(struct nv04_bus_impl) {
- .base.handle = NV_SUBDEV(BUS, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+static int
+nv04_bus_init(struct nouveau_object *object)
+{
+ struct nv04_bus_priv *priv = (void *)object;
+
+ nv_wr32(priv, 0x001100, 0xffffffff);
+ nv_wr32(priv, 0x001140, 0x00000111);
+
+ return nouveau_bus_init(&priv->base);
+}
+
+struct nouveau_oclass
+nv04_bus_oclass = {
+ .handle = NV_SUBDEV(BUS, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_bus_ctor,
.dtor = _nouveau_bus_dtor,
.init = nv04_bus_init,
.fini = _nouveau_bus_fini,
},
- .intr = nv04_bus_intr,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h
deleted file mode 100644
index 4d76024..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __NVKM_BUS_NV04_H__
-#define __NVKM_BUS_NV04_H__
-
-#include <subdev/bus.h>
-
-struct nv04_bus_priv {
- struct nouveau_bus base;
-};
-
-int nv04_bus_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-int nv50_bus_init(struct nouveau_object *);
-void nv50_bus_intr(struct nouveau_subdev *);
-
-struct nv04_bus_impl {
- struct nouveau_oclass base;
- void (*intr)(struct nouveau_subdev *);
- int (*hwsq_exec)(struct nouveau_bus *, u32 *, u32);
- u32 hwsq_size;
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c
index 94da46f..34132ae 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c
@@ -23,7 +23,11 @@
* Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/bus.h>
+
+struct nv31_bus_priv {
+ struct nouveau_bus base;
+};
static void
nv31_bus_intr(struct nouveau_subdev *subdev)
@@ -67,7 +71,7 @@ nv31_bus_intr(struct nouveau_subdev *subdev)
static int
nv31_bus_init(struct nouveau_object *object)
{
- struct nv04_bus_priv *priv = (void *)object;
+ struct nv31_bus_priv *priv = (void *)object;
int ret;
ret = nouveau_bus_init(&priv->base);
@@ -79,14 +83,30 @@ nv31_bus_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv31_bus_oclass = &(struct nv04_bus_impl) {
- .base.handle = NV_SUBDEV(BUS, 0x31),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_bus_ctor,
+static int
+nv31_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv31_bus_priv *priv;
+ int ret;
+
+ ret = nouveau_bus_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nv31_bus_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nv31_bus_oclass = {
+ .handle = NV_SUBDEV(BUS, 0x31),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv31_bus_ctor,
.dtor = _nouveau_bus_dtor,
.init = nv31_bus_init,
.fini = _nouveau_bus_fini,
},
- .intr = nv31_bus_intr,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c
index 11918f7..f5b2117 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c
@@ -23,27 +23,13 @@
* Ben Skeggs
*/
-#include <subdev/timer.h>
+#include <subdev/bus.h>
-#include "nv04.h"
+struct nv50_bus_priv {
+ struct nouveau_bus base;
+};
-static int
-nv50_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size)
-{
- struct nv50_bus_priv *priv = (void *)pbus;
- int i;
-
- nv_mask(pbus, 0x001098, 0x00000008, 0x00000000);
- nv_wr32(pbus, 0x001304, 0x00000000);
- for (i = 0; i < size; i++)
- nv_wr32(priv, 0x001400 + (i * 4), data[i]);
- nv_mask(pbus, 0x001098, 0x00000018, 0x00000018);
- nv_wr32(pbus, 0x00130c, 0x00000003);
-
- return nv_wait(pbus, 0x001308, 0x00000100, 0x00000000) ? 0 : -ETIMEDOUT;
-}
-
-void
+static void
nv50_bus_intr(struct nouveau_subdev *subdev)
{
struct nouveau_bus *pbus = nouveau_bus(subdev);
@@ -75,10 +61,10 @@ nv50_bus_intr(struct nouveau_subdev *subdev)
}
}
-int
+static int
nv50_bus_init(struct nouveau_object *object)
{
- struct nv04_bus_priv *priv = (void *)object;
+ struct nv50_bus_priv *priv = (void *)object;
int ret;
ret = nouveau_bus_init(&priv->base);
@@ -90,16 +76,30 @@ nv50_bus_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv50_bus_oclass = &(struct nv04_bus_impl) {
- .base.handle = NV_SUBDEV(BUS, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_bus_ctor,
+static int
+nv50_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_bus_priv *priv;
+ int ret;
+
+ ret = nouveau_bus_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nv50_bus_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_bus_oclass = {
+ .handle = NV_SUBDEV(BUS, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_bus_ctor,
.dtor = _nouveau_bus_dtor,
.init = nv50_bus_init,
.fini = _nouveau_bus_fini,
},
- .intr = nv50_bus_intr,
- .hwsq_exec = nv50_bus_hwsq_exec,
- .hwsq_size = 64,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c
deleted file mode 100644
index d365905..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2012 Nouveau Community
- *
- * 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: Martin Peres <martin.peres@labri.fr>
- * Ben Skeggs
- */
-
-#include <subdev/timer.h>
-
-#include "nv04.h"
-
-static int
-nv94_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size)
-{
- struct nv50_bus_priv *priv = (void *)pbus;
- int i;
-
- nv_mask(pbus, 0x001098, 0x00000008, 0x00000000);
- nv_wr32(pbus, 0x001304, 0x00000000);
- nv_wr32(pbus, 0x001318, 0x00000000);
- for (i = 0; i < size; i++)
- nv_wr32(priv, 0x080000 + (i * 4), data[i]);
- nv_mask(pbus, 0x001098, 0x00000018, 0x00000018);
- nv_wr32(pbus, 0x00130c, 0x00000001);
-
- return nv_wait(pbus, 0x001308, 0x00000100, 0x00000000) ? 0 : -ETIMEDOUT;
-}
-
-struct nouveau_oclass *
-nv94_bus_oclass = &(struct nv04_bus_impl) {
- .base.handle = NV_SUBDEV(BUS, 0x94),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_bus_ctor,
- .dtor = _nouveau_bus_dtor,
- .init = nv50_bus_init,
- .fini = _nouveau_bus_fini,
- },
- .intr = nv50_bus_intr,
- .hwsq_exec = nv94_bus_hwsq_exec,
- .hwsq_size = 128,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c
index 73839d7..b192d62 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c
@@ -23,7 +23,11 @@
* Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/bus.h>
+
+struct nvc0_bus_priv {
+ struct nouveau_bus base;
+};
static void
nvc0_bus_intr(struct nouveau_subdev *subdev)
@@ -56,7 +60,7 @@ nvc0_bus_intr(struct nouveau_subdev *subdev)
static int
nvc0_bus_init(struct nouveau_object *object)
{
- struct nv04_bus_priv *priv = (void *)object;
+ struct nvc0_bus_priv *priv = (void *)object;
int ret;
ret = nouveau_bus_init(&priv->base);
@@ -68,14 +72,30 @@ nvc0_bus_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nvc0_bus_oclass = &(struct nv04_bus_impl) {
- .base.handle = NV_SUBDEV(BUS, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_bus_ctor,
+static int
+nvc0_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_bus_priv *priv;
+ int ret;
+
+ ret = nouveau_bus_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nvc0_bus_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_bus_oclass = {
+ .handle = NV_SUBDEV(BUS, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_bus_ctor,
.dtor = _nouveau_bus_dtor,
.init = nvc0_bus_init,
.fini = _nouveau_bus_fini,
},
- .intr = nvc0_bus_intr,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c b/drivers/gpu/drm/nouveau/core/subdev/clock/base.c
deleted file mode 100644
index e2938a2..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * 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 <core/option.h>
-
-#include <subdev/clock.h>
-#include <subdev/therm.h>
-#include <subdev/volt.h>
-#include <subdev/fb.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/boost.h>
-#include <subdev/bios/cstep.h>
-#include <subdev/bios/perf.h>
-
-/******************************************************************************
- * misc
- *****************************************************************************/
-static u32
-nouveau_clock_adjust(struct nouveau_clock *clk, bool adjust,
- u8 pstate, u8 domain, u32 input)
-{
- struct nouveau_bios *bios = nouveau_bios(clk);
- struct nvbios_boostE boostE;
- u8 ver, hdr, cnt, len;
- u16 data;
-
- data = nvbios_boostEm(bios, pstate, &ver, &hdr, &cnt, &len, &boostE);
- if (data) {
- struct nvbios_boostS boostS;
- u8 idx = 0, sver, shdr;
- u16 subd;
-
- input = max(boostE.min, input);
- input = min(boostE.max, input);
- do {
- sver = ver;
- shdr = hdr;
- subd = nvbios_boostSp(bios, idx++, data, &sver, &shdr,
- cnt, len, &boostS);
- if (subd && boostS.domain == domain) {
- if (adjust)
- input = input * boostS.percent / 100;
- input = max(boostS.min, input);
- input = min(boostS.max, input);
- break;
- }
- } while (subd);
- }
-
- return input;
-}
-
-/******************************************************************************
- * C-States
- *****************************************************************************/
-static int
-nouveau_cstate_prog(struct nouveau_clock *clk,
- struct nouveau_pstate *pstate, int cstatei)
-{
- struct nouveau_therm *ptherm = nouveau_therm(clk);
- struct nouveau_volt *volt = nouveau_volt(clk);
- struct nouveau_cstate *cstate;
- int ret;
-
- if (!list_empty(&pstate->list)) {
- cstate = list_entry(pstate->list.prev, typeof(*cstate), head);
- } else {
- cstate = &pstate->base;
- }
-
- ret = nouveau_therm_cstate(ptherm, pstate->fanspeed, +1);
- if (ret && ret != -ENODEV) {
- nv_error(clk, "failed to raise fan speed: %d\n", ret);
- return ret;
- }
-
- ret = volt->set_id(volt, cstate->voltage, +1);
- if (ret && ret != -ENODEV) {
- nv_error(clk, "failed to raise voltage: %d\n", ret);
- return ret;
- }
-
- ret = clk->calc(clk, cstate);
- if (ret == 0) {
- ret = clk->prog(clk);
- clk->tidy(clk);
- }
-
- ret = volt->set_id(volt, cstate->voltage, -1);
- if (ret && ret != -ENODEV)
- nv_error(clk, "failed to lower voltage: %d\n", ret);
-
- ret = nouveau_therm_cstate(ptherm, pstate->fanspeed, -1);
- if (ret && ret != -ENODEV)
- nv_error(clk, "failed to lower fan speed: %d\n", ret);
-
- return 0;
-}
-
-static void
-nouveau_cstate_del(struct nouveau_cstate *cstate)
-{
- list_del(&cstate->head);
- kfree(cstate);
-}
-
-static int
-nouveau_cstate_new(struct nouveau_clock *clk, int idx,
- struct nouveau_pstate *pstate)
-{
- struct nouveau_bios *bios = nouveau_bios(clk);
- struct nouveau_clocks *domain = clk->domains;
- struct nouveau_cstate *cstate = NULL;
- struct nvbios_cstepX cstepX;
- u8 ver, hdr;
- u16 data;
-
- data = nvbios_cstepXp(bios, idx, &ver, &hdr, &cstepX);
- if (!data)
- return -ENOENT;
-
- cstate = kzalloc(sizeof(*cstate), GFP_KERNEL);
- if (!cstate)
- return -ENOMEM;
-
- *cstate = pstate->base;
- cstate->voltage = cstepX.voltage;
-
- while (domain && domain->name != nv_clk_src_max) {
- if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) {
- u32 freq = nouveau_clock_adjust(clk, true,
- pstate->pstate,
- domain->bios,
- cstepX.freq);
- cstate->domain[domain->name] = freq;
- }
- domain++;
- }
-
- list_add(&cstate->head, &pstate->list);
- return 0;
-}
-
-/******************************************************************************
- * P-States
- *****************************************************************************/
-static int
-nouveau_pstate_prog(struct nouveau_clock *clk, int pstatei)
-{
- struct nouveau_fb *pfb = nouveau_fb(clk);
- struct nouveau_pstate *pstate;
- int ret, idx = 0;
-
- list_for_each_entry(pstate, &clk->states, head) {
- if (idx++ == pstatei)
- break;
- }
-
- nv_debug(clk, "setting performance state %d\n", pstatei);
- clk->pstate = pstatei;
-
- if (pfb->ram->calc) {
- ret = pfb->ram->calc(pfb, pstate->base.domain[nv_clk_src_mem]);
- if (ret == 0)
- ret = pfb->ram->prog(pfb);
- pfb->ram->tidy(pfb);
- }
-
- return nouveau_cstate_prog(clk, pstate, 0);
-}
-
-static int
-nouveau_pstate_calc(struct nouveau_clock *clk)
-{
- int pstate, ret = 0;
-
- nv_trace(clk, "P %d U %d A %d T %d D %d\n", clk->pstate,
- clk->ustate, clk->astate, clk->tstate, clk->dstate);
-
- if (clk->state_nr && clk->ustate != -1) {
- pstate = (clk->ustate < 0) ? clk->astate : clk->ustate;
- pstate = min(pstate, clk->state_nr - 1 - clk->tstate);
- pstate = max(pstate, clk->dstate);
- } else {
- pstate = clk->pstate = -1;
- }
-
- nv_trace(clk, "-> %d\n", pstate);
- if (pstate != clk->pstate)
- ret = nouveau_pstate_prog(clk, pstate);
- return ret;
-}
-
-static void
-nouveau_pstate_info(struct nouveau_clock *clk, struct nouveau_pstate *pstate)
-{
- struct nouveau_clocks *clock = clk->domains - 1;
- struct nouveau_cstate *cstate;
- char info[3][32] = { "", "", "" };
- char name[4] = "--";
- int i = -1;
-
- if (pstate->pstate != 0xff)
- snprintf(name, sizeof(name), "%02x", pstate->pstate);
-
- while ((++clock)->name != nv_clk_src_max) {
- u32 lo = pstate->base.domain[clock->name];
- u32 hi = lo;
- if (hi == 0)
- continue;
-
- nv_debug(clk, "%02x: %10d KHz\n", clock->name, lo);
- list_for_each_entry(cstate, &pstate->list, head) {
- u32 freq = cstate->domain[clock->name];
- lo = min(lo, freq);
- hi = max(hi, freq);
- nv_debug(clk, "%10d KHz\n", freq);
- }
-
- if (clock->mname && ++i < ARRAY_SIZE(info)) {
- lo /= clock->mdiv;
- hi /= clock->mdiv;
- if (lo == hi) {
- snprintf(info[i], sizeof(info[i]), "%s %d MHz",
- clock->mname, lo);
- } else {
- snprintf(info[i], sizeof(info[i]),
- "%s %d-%d MHz", clock->mname, lo, hi);
- }
- }
- }
-
- nv_info(clk, "%s: %s %s %s\n", name, info[0], info[1], info[2]);
-}
-
-static void
-nouveau_pstate_del(struct nouveau_pstate *pstate)
-{
- struct nouveau_cstate *cstate, *temp;
-
- list_for_each_entry_safe(cstate, temp, &pstate->list, head) {
- nouveau_cstate_del(cstate);
- }
-
- list_del(&pstate->head);
- kfree(pstate);
-}
-
-static int
-nouveau_pstate_new(struct nouveau_clock *clk, int idx)
-{
- struct nouveau_bios *bios = nouveau_bios(clk);
- struct nouveau_clocks *domain = clk->domains - 1;
- struct nouveau_pstate *pstate;
- struct nouveau_cstate *cstate;
- struct nvbios_cstepE cstepE;
- struct nvbios_perfE perfE;
- u8 ver, hdr, cnt, len;
- u16 data;
-
- data = nvbios_perfEp(bios, idx, &ver, &hdr, &cnt, &len, &perfE);
- if (!data)
- return -EINVAL;
- if (perfE.pstate == 0xff)
- return 0;
-
- pstate = kzalloc(sizeof(*pstate), GFP_KERNEL);
- cstate = &pstate->base;
- if (!pstate)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&pstate->list);
-
- pstate->pstate = perfE.pstate;
- pstate->fanspeed = perfE.fanspeed;
- cstate->voltage = perfE.voltage;
- cstate->domain[nv_clk_src_core] = perfE.core;
- cstate->domain[nv_clk_src_shader] = perfE.shader;
- cstate->domain[nv_clk_src_mem] = perfE.memory;
- cstate->domain[nv_clk_src_vdec] = perfE.vdec;
- cstate->domain[nv_clk_src_dom6] = perfE.disp;
-
- while (ver >= 0x40 && (++domain)->name != nv_clk_src_max) {
- struct nvbios_perfS perfS;
- u8 sver = ver, shdr = hdr;
- u32 perfSe = nvbios_perfSp(bios, data, domain->bios,
- &sver, &shdr, cnt, len, &perfS);
- if (perfSe == 0 || sver != 0x40)
- continue;
-
- if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) {
- perfS.v40.freq = nouveau_clock_adjust(clk, false,
- pstate->pstate,
- domain->bios,
- perfS.v40.freq);
- }
-
- cstate->domain[domain->name] = perfS.v40.freq;
- }
-
- data = nvbios_cstepEm(bios, pstate->pstate, &ver, &hdr, &cstepE);
- if (data) {
- int idx = cstepE.index;
- do {
- nouveau_cstate_new(clk, idx, pstate);
- } while(idx--);
- }
-
- nouveau_pstate_info(clk, pstate);
- list_add_tail(&pstate->head, &clk->states);
- clk->state_nr++;
- return 0;
-}
-
-/******************************************************************************
- * Adjustment triggers
- *****************************************************************************/
-static int
-nouveau_clock_ustate_update(struct nouveau_clock *clk, int req)
-{
- struct nouveau_pstate *pstate;
- int i = 0;
-
- /* YKW repellant */
- return -ENOSYS;
-
- if (req != -1 && req != -2) {
- list_for_each_entry(pstate, &clk->states, head) {
- if (pstate->pstate == req)
- break;
- i++;
- }
-
- if (pstate->pstate != req)
- return -EINVAL;
- req = i;
- }
-
- clk->ustate = req;
- return 0;
-}
-
-int
-nouveau_clock_ustate(struct nouveau_clock *clk, int req)
-{
- int ret = nouveau_clock_ustate_update(clk, req);
- if (ret)
- return ret;
- return nouveau_pstate_calc(clk);
-}
-
-int
-nouveau_clock_astate(struct nouveau_clock *clk, int req, int rel)
-{
- if (!rel) clk->astate = req;
- if ( rel) clk->astate += rel;
- clk->astate = min(clk->astate, clk->state_nr - 1);
- clk->astate = max(clk->astate, 0);
- return nouveau_pstate_calc(clk);
-}
-
-int
-nouveau_clock_tstate(struct nouveau_clock *clk, int req, int rel)
-{
- if (!rel) clk->tstate = req;
- if ( rel) clk->tstate += rel;
- clk->tstate = min(clk->tstate, 0);
- clk->tstate = max(clk->tstate, -(clk->state_nr - 1));
- return nouveau_pstate_calc(clk);
-}
-
-int
-nouveau_clock_dstate(struct nouveau_clock *clk, int req, int rel)
-{
- if (!rel) clk->dstate = req;
- if ( rel) clk->dstate += rel;
- clk->dstate = min(clk->dstate, clk->state_nr - 1);
- clk->dstate = max(clk->dstate, 0);
- return nouveau_pstate_calc(clk);
-}
-
-/******************************************************************************
- * subdev base class implementation
- *****************************************************************************/
-int
-_nouveau_clock_init(struct nouveau_object *object)
-{
- struct nouveau_clock *clk = (void *)object;
- struct nouveau_clocks *clock = clk->domains;
- int ret;
-
- memset(&clk->bstate, 0x00, sizeof(clk->bstate));
- INIT_LIST_HEAD(&clk->bstate.list);
- clk->bstate.pstate = 0xff;
-
- while (clock->name != nv_clk_src_max) {
- ret = clk->read(clk, clock->name);
- if (ret < 0) {
- nv_error(clk, "%02x freq unknown\n", clock->name);
- return ret;
- }
- clk->bstate.base.domain[clock->name] = ret;
- clock++;
- }
-
- nouveau_pstate_info(clk, &clk->bstate);
-
- clk->astate = clk->state_nr - 1;
- clk->tstate = 0;
- clk->dstate = 0;
- clk->pstate = -1;
- nouveau_pstate_calc(clk);
- return 0;
-}
-
-void
-_nouveau_clock_dtor(struct nouveau_object *object)
-{
- struct nouveau_clock *clk = (void *)object;
- struct nouveau_pstate *pstate, *temp;
-
- list_for_each_entry_safe(pstate, temp, &clk->states, head) {
- nouveau_pstate_del(pstate);
- }
-
- nouveau_subdev_destroy(&clk->base);
-}
-
-int
-nouveau_clock_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- struct nouveau_clocks *clocks,
- int length, void **object)
-{
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_clock *clk;
- int ret, idx, arglen;
- const char *mode;
-
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "CLK",
- "clock", length, object);
- clk = *object;
- if (ret)
- return ret;
-
- INIT_LIST_HEAD(&clk->states);
- clk->domains = clocks;
- clk->ustate = -1;
-
- idx = 0;
- do {
- ret = nouveau_pstate_new(clk, idx++);
- } while (ret == 0);
-
- mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen);
- if (mode) {
- if (!strncasecmpz(mode, "disabled", arglen)) {
- clk->ustate = -1;
- } else {
- char save = mode[arglen];
- long v;
-
- ((char *)mode)[arglen] = '\0';
- if (!kstrtol(mode, 0, &v))
- nouveau_clock_ustate_update(clk, v);
- ((char *)mode)[arglen] = save;
- }
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
index 30c1f3a..a142775 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
@@ -69,11 +69,6 @@ nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1,
return 0;
}
-static struct nouveau_clocks
-nv04_domain[] = {
- { nv_clk_src_max }
-};
-
static int
nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
@@ -82,7 +77,7 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_clock_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, &priv);
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
index db7346f..0db5dbf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
@@ -23,188 +23,11 @@
*/
#include <subdev/clock.h>
-#include <subdev/bios.h>
-#include <subdev/bios/pll.h>
-
-#include "pll.h"
struct nv40_clock_priv {
struct nouveau_clock base;
- u32 ctrl;
- u32 npll_ctrl;
- u32 npll_coef;
- u32 spll;
-};
-
-static struct nouveau_clocks
-nv40_domain[] = {
- { nv_clk_src_crystal, 0xff },
- { nv_clk_src_href , 0xff },
- { nv_clk_src_core , 0xff, 0, "core", 1000 },
- { nv_clk_src_shader , 0xff, 0, "shader", 1000 },
- { nv_clk_src_mem , 0xff, 0, "memory", 1000 },
- { nv_clk_src_max }
};
-static u32
-read_pll_1(struct nv40_clock_priv *priv, u32 reg)
-{
- u32 ctrl = nv_rd32(priv, reg + 0x00);
- int P = (ctrl & 0x00070000) >> 16;
- int N = (ctrl & 0x0000ff00) >> 8;
- int M = (ctrl & 0x000000ff) >> 0;
- u32 ref = 27000, clk = 0;
-
- if (ctrl & 0x80000000)
- clk = ref * N / M;
-
- return clk >> P;
-}
-
-static u32
-read_pll_2(struct nv40_clock_priv *priv, u32 reg)
-{
- u32 ctrl = nv_rd32(priv, reg + 0x00);
- u32 coef = nv_rd32(priv, reg + 0x04);
- int N2 = (coef & 0xff000000) >> 24;
- int M2 = (coef & 0x00ff0000) >> 16;
- int N1 = (coef & 0x0000ff00) >> 8;
- int M1 = (coef & 0x000000ff) >> 0;
- int P = (ctrl & 0x00070000) >> 16;
- u32 ref = 27000, clk = 0;
-
- if ((ctrl & 0x80000000) && M1) {
- clk = ref * N1 / M1;
- if ((ctrl & 0x40000100) == 0x40000000) {
- if (M2)
- clk = clk * N2 / M2;
- else
- clk = 0;
- }
- }
-
- return clk >> P;
-}
-
-static u32
-read_clk(struct nv40_clock_priv *priv, u32 src)
-{
- switch (src) {
- case 3:
- return read_pll_2(priv, 0x004000);
- case 2:
- return read_pll_1(priv, 0x004008);
- default:
- break;
- }
-
- return 0;
-}
-
-static int
-nv40_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
-{
- struct nv40_clock_priv *priv = (void *)clk;
- u32 mast = nv_rd32(priv, 0x00c040);
-
- switch (src) {
- case nv_clk_src_crystal:
- return nv_device(priv)->crystal;
- case nv_clk_src_href:
- return 100000; /*XXX: PCIE/AGP differ*/
- case nv_clk_src_core:
- return read_clk(priv, (mast & 0x00000003) >> 0);
- case nv_clk_src_shader:
- return read_clk(priv, (mast & 0x00000030) >> 4);
- case nv_clk_src_mem:
- return read_pll_2(priv, 0x4020);
- default:
- break;
- }
-
- nv_debug(priv, "unknown clock source %d 0x%08x\n", src, mast);
- return -EINVAL;
-}
-
-static int
-nv40_clock_calc_pll(struct nv40_clock_priv *priv, u32 reg, u32 clk,
- int *N1, int *M1, int *N2, int *M2, int *log2P)
-{
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll pll;
- int ret;
-
- ret = nvbios_pll_parse(bios, reg, &pll);
- if (ret)
- return ret;
-
- if (clk < pll.vco1.max_freq)
- pll.vco2.max_freq = 0;
-
- ret = nv04_pll_calc(nv_subdev(priv), &pll, clk, N1, M1, N2, M2, log2P);
- if (ret == 0)
- return -ERANGE;
- return ret;
-}
-
-static int
-nv40_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
-{
- struct nv40_clock_priv *priv = (void *)clk;
- int gclk = cstate->domain[nv_clk_src_core];
- int sclk = cstate->domain[nv_clk_src_shader];
- int N1, M1, N2, M2, log2P;
- int ret;
-
- /* core/geometric clock */
- ret = nv40_clock_calc_pll(priv, 0x004000, gclk,
- &N1, &M1, &N2, &M2, &log2P);
- if (ret < 0)
- return ret;
-
- if (N2 == M2) {
- priv->npll_ctrl = 0x80000100 | (log2P << 16);
- priv->npll_coef = (N1 << 8) | M1;
- } else {
- priv->npll_ctrl = 0xc0000000 | (log2P << 16);
- priv->npll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1;
- }
-
- /* use the second pll for shader/rop clock, if it differs from core */
- if (sclk && sclk != gclk) {
- ret = nv40_clock_calc_pll(priv, 0x004008, sclk,
- &N1, &M1, NULL, NULL, &log2P);
- if (ret < 0)
- return ret;
-
- priv->spll = 0xc0000000 | (log2P << 16) | (N1 << 8) | M1;
- priv->ctrl = 0x00000223;
- } else {
- priv->spll = 0x00000000;
- priv->ctrl = 0x00000333;
- }
-
- return 0;
-}
-
-static int
-nv40_clock_prog(struct nouveau_clock *clk)
-{
- struct nv40_clock_priv *priv = (void *)clk;
- nv_mask(priv, 0x00c040, 0x00000333, 0x00000000);
- nv_wr32(priv, 0x004004, priv->npll_coef);
- nv_mask(priv, 0x004000, 0xc0070100, priv->npll_ctrl);
- nv_mask(priv, 0x004008, 0xc007ffff, priv->spll);
- mdelay(5);
- nv_mask(priv, 0x00c040, 0x00000333, priv->ctrl);
- return 0;
-}
-
-static void
-nv40_clock_tidy(struct nouveau_clock *clk)
-{
-}
-
static int
nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
@@ -213,17 +36,13 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv40_clock_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, &priv);
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
priv->base.pll_calc = nv04_clock_pll_calc;
priv->base.pll_prog = nv04_clock_pll_prog;
- priv->base.read = nv40_clock_read;
- priv->base.calc = nv40_clock_calc;
- priv->base.prog = nv40_clock_prog;
- priv->base.tidy = nv40_clock_tidy;
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 250a6d9..d09d3e7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
@@ -22,538 +22,40 @@
* Authors: Ben Skeggs
*/
+#include <subdev/clock.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include "nv50.h"
#include "pll.h"
-#include "seq.h"
-static u32
-read_div(struct nv50_clock_priv *priv)
-{
- switch (nv_device(priv)->chipset) {
- case 0x50: /* it exists, but only has bit 31, not the dividers.. */
- case 0x84:
- case 0x86:
- case 0x98:
- case 0xa0:
- return nv_rd32(priv, 0x004700);
- case 0x92:
- case 0x94:
- case 0x96:
- return nv_rd32(priv, 0x004800);
- default:
- return 0x00000000;
- }
-}
-
-static u32
-read_pll_src(struct nv50_clock_priv *priv, u32 base)
-{
- struct nouveau_clock *clk = &priv->base;
- u32 coef, ref = clk->read(clk, nv_clk_src_crystal);
- u32 rsel = nv_rd32(priv, 0x00e18c);
- int P, N, M, id;
-
- switch (nv_device(priv)->chipset) {
- case 0x50:
- case 0xa0:
- switch (base) {
- case 0x4020:
- case 0x4028: id = !!(rsel & 0x00000004); break;
- case 0x4008: id = !!(rsel & 0x00000008); break;
- case 0x4030: id = 0; break;
- default:
- nv_error(priv, "ref: bad pll 0x%06x\n", base);
- return 0;
- }
-
- coef = nv_rd32(priv, 0x00e81c + (id * 0x0c));
- ref *= (coef & 0x01000000) ? 2 : 4;
- P = (coef & 0x00070000) >> 16;
- N = ((coef & 0x0000ff00) >> 8) + 1;
- M = ((coef & 0x000000ff) >> 0) + 1;
- break;
- case 0x84:
- case 0x86:
- case 0x92:
- coef = nv_rd32(priv, 0x00e81c);
- P = (coef & 0x00070000) >> 16;
- N = (coef & 0x0000ff00) >> 8;
- M = (coef & 0x000000ff) >> 0;
- break;
- case 0x94:
- case 0x96:
- case 0x98:
- rsel = nv_rd32(priv, 0x00c050);
- switch (base) {
- case 0x4020: rsel = (rsel & 0x00000003) >> 0; break;
- case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break;
- case 0x4028: rsel = (rsel & 0x00001800) >> 11; break;
- case 0x4030: rsel = 3; break;
- default:
- nv_error(priv, "ref: bad pll 0x%06x\n", base);
- return 0;
- }
-
- switch (rsel) {
- case 0: id = 1; break;
- case 1: return clk->read(clk, nv_clk_src_crystal);
- case 2: return clk->read(clk, nv_clk_src_href);
- case 3: id = 0; break;
- }
-
- coef = nv_rd32(priv, 0x00e81c + (id * 0x28));
- P = (nv_rd32(priv, 0x00e824 + (id * 0x28)) >> 16) & 7;
- P += (coef & 0x00070000) >> 16;
- N = (coef & 0x0000ff00) >> 8;
- M = (coef & 0x000000ff) >> 0;
- break;
- default:
- BUG_ON(1);
- }
-
- if (M)
- return (ref * N / M) >> P;
- return 0;
-}
-
-static u32
-read_pll_ref(struct nv50_clock_priv *priv, u32 base)
-{
- struct nouveau_clock *clk = &priv->base;
- u32 src, mast = nv_rd32(priv, 0x00c040);
-
- switch (base) {
- case 0x004028:
- src = !!(mast & 0x00200000);
- break;
- case 0x004020:
- src = !!(mast & 0x00400000);
- break;
- case 0x004008:
- src = !!(mast & 0x00010000);
- break;
- case 0x004030:
- src = !!(mast & 0x02000000);
- break;
- case 0x00e810:
- return clk->read(clk, nv_clk_src_crystal);
- default:
- nv_error(priv, "bad pll 0x%06x\n", base);
- return 0;
- }
-
- if (src)
- return clk->read(clk, nv_clk_src_href);
- return read_pll_src(priv, base);
-}
-
-static u32
-read_pll(struct nv50_clock_priv *priv, u32 base)
-{
- struct nouveau_clock *clk = &priv->base;
- u32 mast = nv_rd32(priv, 0x00c040);
- u32 ctrl = nv_rd32(priv, base + 0);
- u32 coef = nv_rd32(priv, base + 4);
- u32 ref = read_pll_ref(priv, base);
- u32 freq = 0;
- int N1, N2, M1, M2;
-
- if (base == 0x004028 && (mast & 0x00100000)) {
- /* wtf, appears to only disable post-divider on nva0 */
- if (nv_device(priv)->chipset != 0xa0)
- return clk->read(clk, nv_clk_src_dom6);
- }
-
- N2 = (coef & 0xff000000) >> 24;
- M2 = (coef & 0x00ff0000) >> 16;
- N1 = (coef & 0x0000ff00) >> 8;
- M1 = (coef & 0x000000ff);
- if ((ctrl & 0x80000000) && M1) {
- freq = ref * N1 / M1;
- if ((ctrl & 0x40000100) == 0x40000000) {
- if (M2)
- freq = freq * N2 / M2;
- else
- freq = 0;
- }
- }
-
- return freq;
-}
-
-static int
-nv50_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
-{
- struct nv50_clock_priv *priv = (void *)clk;
- u32 mast = nv_rd32(priv, 0x00c040);
- u32 P = 0;
-
- switch (src) {
- case nv_clk_src_crystal:
- return nv_device(priv)->crystal;
- case nv_clk_src_href:
- return 100000; /* PCIE reference clock */
- case nv_clk_src_hclk:
- return div_u64((u64)clk->read(clk, nv_clk_src_href) * 27778, 10000);
- case nv_clk_src_hclkm3:
- return clk->read(clk, nv_clk_src_hclk) * 3;
- case nv_clk_src_hclkm3d2:
- return clk->read(clk, nv_clk_src_hclk) * 3 / 2;
- case nv_clk_src_host:
- switch (mast & 0x30000000) {
- case 0x00000000: return clk->read(clk, nv_clk_src_href);
- case 0x10000000: break;
- case 0x20000000: /* !0x50 */
- case 0x30000000: return clk->read(clk, nv_clk_src_hclk);
- }
- break;
- case nv_clk_src_core:
- if (!(mast & 0x00100000))
- P = (nv_rd32(priv, 0x004028) & 0x00070000) >> 16;
- switch (mast & 0x00000003) {
- case 0x00000000: return clk->read(clk, nv_clk_src_crystal) >> P;
- case 0x00000001: return clk->read(clk, nv_clk_src_dom6);
- case 0x00000002: return read_pll(priv, 0x004020) >> P;
- case 0x00000003: return read_pll(priv, 0x004028) >> P;
- }
- break;
- case nv_clk_src_shader:
- P = (nv_rd32(priv, 0x004020) & 0x00070000) >> 16;
- switch (mast & 0x00000030) {
- case 0x00000000:
- if (mast & 0x00000080)
- return clk->read(clk, nv_clk_src_host) >> P;
- return clk->read(clk, nv_clk_src_crystal) >> P;
- case 0x00000010: break;
- case 0x00000020: return read_pll(priv, 0x004028) >> P;
- case 0x00000030: return read_pll(priv, 0x004020) >> P;
- }
- break;
- case nv_clk_src_mem:
- P = (nv_rd32(priv, 0x004008) & 0x00070000) >> 16;
- if (nv_rd32(priv, 0x004008) & 0x00000200) {
- switch (mast & 0x0000c000) {
- case 0x00000000:
- return clk->read(clk, nv_clk_src_crystal) >> P;
- case 0x00008000:
- case 0x0000c000:
- return clk->read(clk, nv_clk_src_href) >> P;
- }
- } else {
- return read_pll(priv, 0x004008) >> P;
- }
- break;
- case nv_clk_src_vdec:
- P = (read_div(priv) & 0x00000700) >> 8;
- switch (nv_device(priv)->chipset) {
- case 0x84:
- case 0x86:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0xa0:
- switch (mast & 0x00000c00) {
- case 0x00000000:
- if (nv_device(priv)->chipset == 0xa0) /* wtf?? */
- return clk->read(clk, nv_clk_src_core) >> P;
- return clk->read(clk, nv_clk_src_crystal) >> P;
- case 0x00000400:
- return 0;
- case 0x00000800:
- if (mast & 0x01000000)
- return read_pll(priv, 0x004028) >> P;
- return read_pll(priv, 0x004030) >> P;
- case 0x00000c00:
- return clk->read(clk, nv_clk_src_core) >> P;
- }
- break;
- case 0x98:
- switch (mast & 0x00000c00) {
- case 0x00000000:
- return clk->read(clk, nv_clk_src_core) >> P;
- case 0x00000400:
- return 0;
- case 0x00000800:
- return clk->read(clk, nv_clk_src_hclkm3d2) >> P;
- case 0x00000c00:
- return clk->read(clk, nv_clk_src_mem) >> P;
- }
- break;
- }
- break;
- case nv_clk_src_dom6:
- switch (nv_device(priv)->chipset) {
- case 0x50:
- case 0xa0:
- return read_pll(priv, 0x00e810) >> 2;
- case 0x84:
- case 0x86:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0x98:
- P = (read_div(priv) & 0x00000007) >> 0;
- switch (mast & 0x0c000000) {
- case 0x00000000: return clk->read(clk, nv_clk_src_href);
- case 0x04000000: break;
- case 0x08000000: return clk->read(clk, nv_clk_src_hclk);
- case 0x0c000000:
- return clk->read(clk, nv_clk_src_hclkm3) >> P;
- }
- break;
- default:
- break;
- }
- default:
- break;
- }
-
- nv_debug(priv, "unknown clock source %d 0x%08x\n", src, mast);
- return -EINVAL;
-}
-
-static u32
-calc_pll(struct nv50_clock_priv *priv, u32 reg, u32 clk, int *N, int *M, int *P)
-{
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll pll;
- int ret;
-
- ret = nvbios_pll_parse(bios, reg, &pll);
- if (ret)
- return 0;
-
- pll.vco2.max_freq = 0;
- pll.refclk = read_pll_ref(priv, reg);
- if (!pll.refclk)
- return 0;
-
- return nv04_pll_calc(nv_subdev(priv), &pll, clk, N, M, NULL, NULL, P);
-}
-
-static inline u32
-calc_div(u32 src, u32 target, int *div)
-{
- u32 clk0 = src, clk1 = src;
- for (*div = 0; *div <= 7; (*div)++) {
- if (clk0 <= target) {
- clk1 = clk0 << (*div ? 1 : 0);
- break;
- }
- clk0 >>= 1;
- }
-
- if (target - clk0 <= clk1 - target)
- return clk0;
- (*div)--;
- return clk1;
-}
-
-static inline u32
-clk_same(u32 a, u32 b)
-{
- return ((a / 1000) == (b / 1000));
-}
-
-static int
-nv50_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
-{
- struct nv50_clock_priv *priv = (void *)clk;
- struct nv50_clock_hwsq *hwsq = &priv->hwsq;
- const int shader = cstate->domain[nv_clk_src_shader];
- const int core = cstate->domain[nv_clk_src_core];
- const int vdec = cstate->domain[nv_clk_src_vdec];
- const int dom6 = cstate->domain[nv_clk_src_dom6];
- u32 mastm = 0, mastv = 0;
- u32 divsm = 0, divsv = 0;
- int N, M, P1, P2;
- int freq, out;
-
- /* prepare a hwsq script from which we'll perform the reclock */
- out = clk_init(hwsq, nv_subdev(clk));
- if (out)
- return out;
-
- clk_wr32(hwsq, fifo, 0x00000001); /* block fifo */
- clk_nsec(hwsq, 8000);
- clk_setf(hwsq, 0x10, 0x00); /* disable fb */
- clk_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
-
- /* vdec: avoid modifying xpll until we know exactly how the other
- * clock domains work, i suspect at least some of them can also be
- * tied to xpll...
- */
- if (vdec) {
- /* see how close we can get using nvclk as a source */
- freq = calc_div(core, vdec, &P1);
-
- /* see how close we can get using xpll/hclk as a source */
- if (nv_device(priv)->chipset != 0x98)
- out = read_pll(priv, 0x004030);
- else
- out = clk->read(clk, nv_clk_src_hclkm3d2);
- out = calc_div(out, vdec, &P2);
-
- /* select whichever gets us closest */
- if (abs(vdec - freq) <= abs(vdec - out)) {
- if (nv_device(priv)->chipset != 0x98)
- mastv |= 0x00000c00;
- divsv |= P1 << 8;
- } else {
- mastv |= 0x00000800;
- divsv |= P2 << 8;
- }
-
- mastm |= 0x00000c00;
- divsm |= 0x00000700;
- }
-
- /* dom6: nfi what this is, but we're limited to various combinations
- * of the host clock frequency
- */
- if (dom6) {
- if (clk_same(dom6, clk->read(clk, nv_clk_src_href))) {
- mastv |= 0x00000000;
- } else
- if (clk_same(dom6, clk->read(clk, nv_clk_src_hclk))) {
- mastv |= 0x08000000;
- } else {
- freq = clk->read(clk, nv_clk_src_hclk) * 3;
- freq = calc_div(freq, dom6, &P1);
-
- mastv |= 0x0c000000;
- divsv |= P1;
- }
-
- mastm |= 0x0c000000;
- divsm |= 0x00000007;
- }
-
- /* vdec/dom6: switch to "safe" clocks temporarily, update dividers
- * and then switch to target clocks
- */
- clk_mask(hwsq, mast, mastm, 0x00000000);
- clk_mask(hwsq, divs, divsm, divsv);
- clk_mask(hwsq, mast, mastm, mastv);
-
- /* core/shader: disconnect nvclk/sclk from their PLLs (nvclk to dom6,
- * sclk to hclk) before reprogramming
- */
- if (nv_device(priv)->chipset < 0x92)
- clk_mask(hwsq, mast, 0x001000b0, 0x00100080);
- else
- clk_mask(hwsq, mast, 0x000000b3, 0x00000081);
-
- /* core: for the moment at least, always use nvpll */
- freq = calc_pll(priv, 0x4028, core, &N, &M, &P1);
- if (freq == 0)
- return -ERANGE;
-
- clk_mask(hwsq, nvpll[0], 0xc03f0100,
- 0x80000000 | (P1 << 19) | (P1 << 16));
- clk_mask(hwsq, nvpll[1], 0x0000ffff, (N << 8) | M);
-
- /* shader: tie to nvclk if possible, otherwise use spll. have to be
- * very careful that the shader clock is at least twice the core, or
- * some chipsets will be very unhappy. i expect most or all of these
- * cases will be handled by tying to nvclk, but it's possible there's
- * corners
- */
- if (P1-- && shader == (core << 1)) {
- clk_mask(hwsq, spll[0], 0xc03f0100, (P1 << 19) | (P1 << 16));
- clk_mask(hwsq, mast, 0x00100033, 0x00000023);
- } else {
- freq = calc_pll(priv, 0x4020, shader, &N, &M, &P1);
- if (freq == 0)
- return -ERANGE;
-
- clk_mask(hwsq, spll[0], 0xc03f0100,
- 0x80000000 | (P1 << 19) | (P1 << 16));
- clk_mask(hwsq, spll[1], 0x0000ffff, (N << 8) | M);
- clk_mask(hwsq, mast, 0x00100033, 0x00000033);
- }
-
- /* restore normal operation */
- clk_setf(hwsq, 0x10, 0x01); /* enable fb */
- clk_wait(hwsq, 0x00, 0x00); /* wait for fb enabled */
- clk_wr32(hwsq, fifo, 0x00000000); /* un-block fifo */
- return 0;
-}
+struct nv50_clock_priv {
+ struct nouveau_clock base;
+};
static int
-nv50_clock_prog(struct nouveau_clock *clk)
-{
- struct nv50_clock_priv *priv = (void *)clk;
- return clk_exec(&priv->hwsq, true);
-}
-
-static void
-nv50_clock_tidy(struct nouveau_clock *clk)
-{
- struct nv50_clock_priv *priv = (void *)clk;
- clk_exec(&priv->hwsq, false);
-}
-
-int
nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv50_clock_oclass *pclass = (void *)oclass;
struct nv50_clock_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
- &priv);
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->hwsq.r_fifo = hwsq_reg(0x002504);
- priv->hwsq.r_spll[0] = hwsq_reg(0x004020);
- priv->hwsq.r_spll[1] = hwsq_reg(0x004024);
- priv->hwsq.r_nvpll[0] = hwsq_reg(0x004028);
- priv->hwsq.r_nvpll[1] = hwsq_reg(0x00402c);
- switch (nv_device(priv)->chipset) {
- case 0x92:
- case 0x94:
- case 0x96:
- priv->hwsq.r_divs = hwsq_reg(0x004800);
- break;
- default:
- priv->hwsq.r_divs = hwsq_reg(0x004700);
- break;
- }
- priv->hwsq.r_mast = hwsq_reg(0x00c040);
-
- priv->base.read = nv50_clock_read;
- priv->base.calc = nv50_clock_calc;
- priv->base.prog = nv50_clock_prog;
- priv->base.tidy = nv50_clock_tidy;
+ priv->base.pll_calc = nv04_clock_pll_calc;
return 0;
}
-static struct nouveau_clocks
-nv50_domains[] = {
- { nv_clk_src_crystal, 0xff },
- { nv_clk_src_href , 0xff },
- { nv_clk_src_core , 0xff, 0, "core", 1000 },
- { nv_clk_src_shader , 0xff, 0, "shader", 1000 },
- { nv_clk_src_mem , 0xff, 0, "memory", 1000 },
- { nv_clk_src_max }
-};
-
-struct nouveau_oclass *
-nv50_clock_oclass = &(struct nv50_clock_oclass) {
- .base.handle = NV_SUBDEV(CLOCK, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass
+nv50_clock_oclass = {
+ .handle = NV_SUBDEV(CLOCK, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_clock_ctor,
.dtor = _nouveau_clock_dtor,
.init = _nouveau_clock_init,
.fini = _nouveau_clock_fini,
},
- .domains = nv50_domains,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h
deleted file mode 100644
index f10917d..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __NVKM_CLK_NV50_H__
-#define __NVKM_CLK_NV50_H__
-
-#include <subdev/bus.h>
-#include <subdev/bus/hwsq.h>
-#include <subdev/clock.h>
-
-struct nv50_clock_hwsq {
- struct hwsq base;
- struct hwsq_reg r_fifo;
- struct hwsq_reg r_spll[2];
- struct hwsq_reg r_nvpll[2];
- struct hwsq_reg r_divs;
- struct hwsq_reg r_mast;
-};
-
-struct nv50_clock_priv {
- struct nouveau_clock base;
- struct nv50_clock_hwsq hwsq;
-};
-
-int nv50_clock_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-struct nv50_clock_oclass {
- struct nouveau_oclass base;
- struct nouveau_clocks *domains;
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c
deleted file mode 100644
index b0b7c14..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 <bskeggs@redhat.com>
- */
-
-#include "nv50.h"
-
-static struct nouveau_clocks
-nv84_domains[] = {
- { nv_clk_src_crystal, 0xff },
- { nv_clk_src_href , 0xff },
- { nv_clk_src_core , 0xff, 0, "core", 1000 },
- { nv_clk_src_shader , 0xff, 0, "shader", 1000 },
- { nv_clk_src_mem , 0xff, 0, "memory", 1000 },
- { nv_clk_src_vdec , 0xff },
- { nv_clk_src_max }
-};
-
-struct nouveau_oclass *
-nv84_clock_oclass = &(struct nv50_clock_oclass) {
- .base.handle = NV_SUBDEV(CLOCK, 0x84),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
- },
- .domains = nv84_domains,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index 4f5a137..f074cd2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -22,277 +22,33 @@
* Authors: Ben Skeggs
*/
+#include <subdev/clock.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include <subdev/timer.h>
#include "pll.h"
-#include "nva3.h"
-
struct nva3_clock_priv {
struct nouveau_clock base;
- struct nva3_clock_info eng[nv_clk_src_max];
};
-static u32 read_clk(struct nva3_clock_priv *, int, bool);
-static u32 read_pll(struct nva3_clock_priv *, int, u32);
-
-static u32
-read_vco(struct nva3_clock_priv *priv, int clk)
-{
- u32 sctl = nv_rd32(priv, 0x4120 + (clk * 4));
- if ((sctl & 0x00000030) != 0x00000030)
- return read_pll(priv, 0x41, 0x00e820);
- return read_pll(priv, 0x42, 0x00e8a0);
-}
-
-static u32
-read_clk(struct nva3_clock_priv *priv, int clk, bool ignore_en)
-{
- u32 sctl, sdiv, sclk;
-
- /* refclk for the 0xe8xx plls is a fixed frequency */
- if (clk >= 0x40) {
- if (nv_device(priv)->chipset == 0xaf) {
- /* no joke.. seriously.. sigh.. */
- return nv_rd32(priv, 0x00471c) * 1000;
- }
-
- return nv_device(priv)->crystal;
- }
-
- sctl = nv_rd32(priv, 0x4120 + (clk * 4));
- if (!ignore_en && !(sctl & 0x00000100))
- return 0;
-
- switch (sctl & 0x00003000) {
- case 0x00000000:
- return nv_device(priv)->crystal;
- case 0x00002000:
- if (sctl & 0x00000040)
- return 108000;
- return 100000;
- case 0x00003000:
- sclk = read_vco(priv, clk);
- sdiv = ((sctl & 0x003f0000) >> 16) + 2;
- return (sclk * 2) / sdiv;
- default:
- return 0;
- }
-}
-
-static u32
-read_pll(struct nva3_clock_priv *priv, int clk, u32 pll)
-{
- u32 ctrl = nv_rd32(priv, pll + 0);
- u32 sclk = 0, P = 1, N = 1, M = 1;
-
- if (!(ctrl & 0x00000008)) {
- if (ctrl & 0x00000001) {
- u32 coef = nv_rd32(priv, pll + 4);
- M = (coef & 0x000000ff) >> 0;
- N = (coef & 0x0000ff00) >> 8;
- P = (coef & 0x003f0000) >> 16;
-
- /* no post-divider on these.. */
- if ((pll & 0x00ff00) == 0x00e800)
- P = 1;
-
- sclk = read_clk(priv, 0x00 + clk, false);
- }
- } else {
- sclk = read_clk(priv, 0x10 + clk, false);
- }
-
- if (M * P)
- return sclk * N / (M * P);
- return 0;
-}
-
-static int
-nva3_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
-{
- struct nva3_clock_priv *priv = (void *)clk;
-
- switch (src) {
- case nv_clk_src_crystal:
- return nv_device(priv)->crystal;
- case nv_clk_src_href:
- return 100000;
- case nv_clk_src_core:
- return read_pll(priv, 0x00, 0x4200);
- case nv_clk_src_shader:
- return read_pll(priv, 0x01, 0x4220);
- case nv_clk_src_mem:
- return read_pll(priv, 0x02, 0x4000);
- case nv_clk_src_disp:
- return read_clk(priv, 0x20, false);
- case nv_clk_src_vdec:
- return read_clk(priv, 0x21, false);
- case nv_clk_src_daemon:
- return read_clk(priv, 0x25, false);
- default:
- nv_error(clk, "invalid clock source %d\n", src);
- return -EINVAL;
- }
-}
-
int
-nva3_clock_info(struct nouveau_clock *clock, int clk, u32 pll, u32 khz,
- struct nva3_clock_info *info)
+nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+ int clk, struct nouveau_pll_vals *pv)
{
- struct nouveau_bios *bios = nouveau_bios(clock);
- struct nva3_clock_priv *priv = (void *)clock;
- struct nvbios_pll limits;
- u32 oclk, sclk, sdiv;
- int P, N, M, diff;
- int ret;
-
- info->pll = 0;
- info->clk = 0;
-
- switch (khz) {
- case 27000:
- info->clk = 0x00000100;
- return khz;
- case 100000:
- info->clk = 0x00002100;
- return khz;
- case 108000:
- info->clk = 0x00002140;
- return khz;
- default:
- sclk = read_vco(priv, clk);
- sdiv = min((sclk * 2) / (khz - 2999), (u32)65);
- /* if the clock has a PLL attached, and we can get a within
- * [-2, 3) MHz of a divider, we'll disable the PLL and use
- * the divider instead.
- *
- * divider can go as low as 2, limited here because NVIDIA
- * and the VBIOS on my NVA8 seem to prefer using the PLL
- * for 810MHz - is there a good reason?
- */
- if (sdiv > 4) {
- oclk = (sclk * 2) / sdiv;
- diff = khz - oclk;
- if (!pll || (diff >= -2000 && diff < 3000)) {
- info->clk = (((sdiv - 2) << 16) | 0x00003100);
- return oclk;
- }
- }
-
- if (!pll)
- return -ERANGE;
- break;
- }
+ int ret, N, M, P;
- ret = nvbios_pll_parse(bios, pll, &limits);
- if (ret)
- return ret;
-
- limits.refclk = read_clk(priv, clk - 0x10, true);
- if (!limits.refclk)
- return -EINVAL;
+ ret = nva3_pll_calc(nv_subdev(clock), info, clk, &N, NULL, &M, &P);
- ret = nva3_pll_calc(nv_subdev(priv), &limits, khz, &N, NULL, &M, &P);
- if (ret >= 0) {
- info->clk = nv_rd32(priv, 0x4120 + (clk * 4));
- info->pll = (P << 16) | (N << 8) | M;
+ if (ret > 0) {
+ pv->refclk = info->refclk;
+ pv->N1 = N;
+ pv->M1 = M;
+ pv->log2P = P;
}
-
- return ret ? ret : -ERANGE;
-}
-
-static int
-calc_clk(struct nva3_clock_priv *priv, struct nouveau_cstate *cstate,
- int clk, u32 pll, int idx)
-{
- int ret = nva3_clock_info(&priv->base, clk, pll, cstate->domain[idx],
- &priv->eng[idx]);
- if (ret >= 0)
- return 0;
return ret;
}
-static void
-prog_pll(struct nva3_clock_priv *priv, int clk, u32 pll, int idx)
-{
- struct nva3_clock_info *info = &priv->eng[idx];
- const u32 src0 = 0x004120 + (clk * 4);
- const u32 src1 = 0x004160 + (clk * 4);
- const u32 ctrl = pll + 0;
- const u32 coef = pll + 4;
-
- if (info->pll) {
- nv_mask(priv, src0, 0x00000101, 0x00000101);
- nv_wr32(priv, coef, info->pll);
- nv_mask(priv, ctrl, 0x00000015, 0x00000015);
- nv_mask(priv, ctrl, 0x00000010, 0x00000000);
- nv_wait(priv, ctrl, 0x00020000, 0x00020000);
- nv_mask(priv, ctrl, 0x00000010, 0x00000010);
- nv_mask(priv, ctrl, 0x00000008, 0x00000000);
- nv_mask(priv, src1, 0x00000100, 0x00000000);
- nv_mask(priv, src1, 0x00000001, 0x00000000);
- } else {
- nv_mask(priv, src1, 0x003f3141, 0x00000101 | info->clk);
- nv_mask(priv, ctrl, 0x00000018, 0x00000018);
- udelay(20);
- nv_mask(priv, ctrl, 0x00000001, 0x00000000);
- nv_mask(priv, src0, 0x00000100, 0x00000000);
- nv_mask(priv, src0, 0x00000001, 0x00000000);
- }
-}
-
-static void
-prog_clk(struct nva3_clock_priv *priv, int clk, int idx)
-{
- struct nva3_clock_info *info = &priv->eng[idx];
- nv_mask(priv, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | info->clk);
-}
-
-static int
-nva3_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
-{
- struct nva3_clock_priv *priv = (void *)clk;
- int ret;
-
- if ((ret = calc_clk(priv, cstate, 0x10, 0x4200, nv_clk_src_core)) ||
- (ret = calc_clk(priv, cstate, 0x11, 0x4220, nv_clk_src_shader)) ||
- (ret = calc_clk(priv, cstate, 0x20, 0x0000, nv_clk_src_disp)) ||
- (ret = calc_clk(priv, cstate, 0x21, 0x0000, nv_clk_src_vdec)))
- return ret;
-
- return 0;
-}
-
-static int
-nva3_clock_prog(struct nouveau_clock *clk)
-{
- struct nva3_clock_priv *priv = (void *)clk;
- prog_pll(priv, 0x00, 0x004200, nv_clk_src_core);
- prog_pll(priv, 0x01, 0x004220, nv_clk_src_shader);
- prog_clk(priv, 0x20, nv_clk_src_disp);
- prog_clk(priv, 0x21, nv_clk_src_vdec);
- return 0;
-}
-
-static void
-nva3_clock_tidy(struct nouveau_clock *clk)
-{
-}
-
-static struct nouveau_clocks
-nva3_domain[] = {
- { nv_clk_src_crystal, 0xff },
- { nv_clk_src_href , 0xff },
- { nv_clk_src_core , 0x00, 0, "core", 1000 },
- { nv_clk_src_shader , 0x01, 0, "shader", 1000 },
- { nv_clk_src_mem , 0x02, 0, "memory", 1000 },
- { nv_clk_src_vdec , 0x03 },
- { nv_clk_src_disp , 0x04 },
- { nv_clk_src_max }
-};
static int
nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -302,15 +58,12 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nva3_clock_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, &priv);
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.read = nva3_clock_read;
- priv->base.calc = nva3_clock_calc;
- priv->base.prog = nva3_clock_prog;
- priv->base.tidy = nva3_clock_tidy;
+ priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h
deleted file mode 100644
index 6229a50..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __NVKM_CLK_NVA3_H__
-#define __NVKM_CLK_NVA3_H__
-
-#include <subdev/clock.h>
-
-struct nva3_clock_info {
- u32 clk;
- u32 pll;
-};
-
-int nva3_clock_info(struct nouveau_clock *, int, u32, u32,
- struct nva3_clock_info *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c
deleted file mode 100644
index 7a723b4..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * 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 <engine/fifo.h>
-#include <subdev/bios.h>
-#include <subdev/bios/pll.h>
-#include <subdev/timer.h>
-#include <subdev/clock.h>
-
-#include "pll.h"
-
-struct nvaa_clock_priv {
- struct nouveau_clock base;
- enum nv_clk_src csrc, ssrc, vsrc;
- u32 cctrl, sctrl;
- u32 ccoef, scoef;
- u32 cpost, spost;
- u32 vdiv;
-};
-
-static u32
-read_div(struct nouveau_clock *clk)
-{
- return nv_rd32(clk, 0x004600);
-}
-
-static u32
-read_pll(struct nouveau_clock *clk, u32 base)
-{
- u32 ctrl = nv_rd32(clk, base + 0);
- u32 coef = nv_rd32(clk, base + 4);
- u32 ref = clk->read(clk, nv_clk_src_href);
- u32 post_div = 0;
- u32 clock = 0;
- int N1, M1;
-
- switch (base){
- case 0x4020:
- post_div = 1 << ((nv_rd32(clk, 0x4070) & 0x000f0000) >> 16);
- break;
- case 0x4028:
- post_div = (nv_rd32(clk, 0x4040) & 0x000f0000) >> 16;
- break;
- default:
- break;
- }
-
- N1 = (coef & 0x0000ff00) >> 8;
- M1 = (coef & 0x000000ff);
- if ((ctrl & 0x80000000) && M1) {
- clock = ref * N1 / M1;
- clock = clock / post_div;
- }
-
- return clock;
-}
-
-static int
-nvaa_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
-{
- struct nvaa_clock_priv *priv = (void *)clk;
- u32 mast = nv_rd32(clk, 0x00c054);
- u32 P = 0;
-
- switch (src) {
- case nv_clk_src_crystal:
- return nv_device(priv)->crystal;
- case nv_clk_src_href:
- return 100000; /* PCIE reference clock */
- case nv_clk_src_hclkm4:
- return clk->read(clk, nv_clk_src_href) * 4;
- case nv_clk_src_hclkm2d3:
- return clk->read(clk, nv_clk_src_href) * 2 / 3;
- case nv_clk_src_host:
- switch (mast & 0x000c0000) {
- case 0x00000000: return clk->read(clk, nv_clk_src_hclkm2d3);
- case 0x00040000: break;
- case 0x00080000: return clk->read(clk, nv_clk_src_hclkm4);
- case 0x000c0000: return clk->read(clk, nv_clk_src_cclk);
- }
- break;
- case nv_clk_src_core:
- P = (nv_rd32(clk, 0x004028) & 0x00070000) >> 16;
-
- switch (mast & 0x00000003) {
- case 0x00000000: return clk->read(clk, nv_clk_src_crystal) >> P;
- case 0x00000001: return 0;
- case 0x00000002: return clk->read(clk, nv_clk_src_hclkm4) >> P;
- case 0x00000003: return read_pll(clk, 0x004028) >> P;
- }
- break;
- case nv_clk_src_cclk:
- if ((mast & 0x03000000) != 0x03000000)
- return clk->read(clk, nv_clk_src_core);
-
- if ((mast & 0x00000200) == 0x00000000)
- return clk->read(clk, nv_clk_src_core);
-
- switch (mast & 0x00000c00) {
- case 0x00000000: return clk->read(clk, nv_clk_src_href);
- case 0x00000400: return clk->read(clk, nv_clk_src_hclkm4);
- case 0x00000800: return clk->read(clk, nv_clk_src_hclkm2d3);
- default: return 0;
- }
- case nv_clk_src_shader:
- P = (nv_rd32(clk, 0x004020) & 0x00070000) >> 16;
- switch (mast & 0x00000030) {
- case 0x00000000:
- if (mast & 0x00000040)
- return clk->read(clk, nv_clk_src_href) >> P;
- return clk->read(clk, nv_clk_src_crystal) >> P;
- case 0x00000010: break;
- case 0x00000020: return read_pll(clk, 0x004028) >> P;
- case 0x00000030: return read_pll(clk, 0x004020) >> P;
- }
- break;
- case nv_clk_src_mem:
- return 0;
- break;
- case nv_clk_src_vdec:
- P = (read_div(clk) & 0x00000700) >> 8;
-
- switch (mast & 0x00400000) {
- case 0x00400000:
- return clk->read(clk, nv_clk_src_core) >> P;
- break;
- default:
- return 500000 >> P;
- break;
- }
- break;
- default:
- break;
- }
-
- nv_debug(priv, "unknown clock source %d 0x%08x\n", src, mast);
- return 0;
-}
-
-static u32
-calc_pll(struct nvaa_clock_priv *priv, u32 reg,
- u32 clock, int *N, int *M, int *P)
-{
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll pll;
- struct nouveau_clock *clk = &priv->base;
- int ret;
-
- ret = nvbios_pll_parse(bios, reg, &pll);
- if (ret)
- return 0;
-
- pll.vco2.max_freq = 0;
- pll.refclk = clk->read(clk, nv_clk_src_href);
- if (!pll.refclk)
- return 0;
-
- return nv04_pll_calc(nv_subdev(priv), &pll, clock, N, M, NULL, NULL, P);
-}
-
-static inline u32
-calc_P(u32 src, u32 target, int *div)
-{
- u32 clk0 = src, clk1 = src;
- for (*div = 0; *div <= 7; (*div)++) {
- if (clk0 <= target) {
- clk1 = clk0 << (*div ? 1 : 0);
- break;
- }
- clk0 >>= 1;
- }
-
- if (target - clk0 <= clk1 - target)
- return clk0;
- (*div)--;
- return clk1;
-}
-
-static int
-nvaa_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
-{
- struct nvaa_clock_priv *priv = (void *)clk;
- const int shader = cstate->domain[nv_clk_src_shader];
- const int core = cstate->domain[nv_clk_src_core];
- const int vdec = cstate->domain[nv_clk_src_vdec];
- u32 out = 0, clock = 0;
- int N, M, P1, P2 = 0;
- int divs = 0;
-
- /* cclk: find suitable source, disable PLL if we can */
- if (core < clk->read(clk, nv_clk_src_hclkm4))
- out = calc_P(clk->read(clk, nv_clk_src_hclkm4), core, &divs);
-
- /* Calculate clock * 2, so shader clock can use it too */
- clock = calc_pll(priv, 0x4028, (core << 1), &N, &M, &P1);
-
- if (abs(core - out) <=
- abs(core - (clock >> 1))) {
- priv->csrc = nv_clk_src_hclkm4;
- priv->cctrl = divs << 16;
- } else {
- /* NVCTRL is actually used _after_ NVPOST, and after what we
- * call NVPLL. To make matters worse, NVPOST is an integer
- * divider instead of a right-shift number. */
- if(P1 > 2) {
- P2 = P1 - 2;
- P1 = 2;
- }
-
- priv->csrc = nv_clk_src_core;
- priv->ccoef = (N << 8) | M;
-
- priv->cctrl = (P2 + 1) << 16;
- priv->cpost = (1 << P1) << 16;
- }
-
- /* sclk: nvpll + divisor, href or spll */
- out = 0;
- if (shader == clk->read(clk, nv_clk_src_href)) {
- priv->ssrc = nv_clk_src_href;
- } else {
- clock = calc_pll(priv, 0x4020, shader, &N, &M, &P1);
- if (priv->csrc == nv_clk_src_core) {
- out = calc_P((core << 1), shader, &divs);
- }
-
- if (abs(shader - out) <=
- abs(shader - clock) &&
- (divs + P2) <= 7) {
- priv->ssrc = nv_clk_src_core;
- priv->sctrl = (divs + P2) << 16;
- } else {
- priv->ssrc = nv_clk_src_shader;
- priv->scoef = (N << 8) | M;
- priv->sctrl = P1 << 16;
- }
- }
-
- /* vclk */
- out = calc_P(core, vdec, &divs);
- clock = calc_P(500000, vdec, &P1);
- if(abs(vdec - out) <=
- abs(vdec - clock)) {
- priv->vsrc = nv_clk_src_cclk;
- priv->vdiv = divs << 16;
- } else {
- priv->vsrc = nv_clk_src_vdec;
- priv->vdiv = P1 << 16;
- }
-
- /* Print strategy! */
- nv_debug(priv, "nvpll: %08x %08x %08x\n",
- priv->ccoef, priv->cpost, priv->cctrl);
- nv_debug(priv, " spll: %08x %08x %08x\n",
- priv->scoef, priv->spost, priv->sctrl);
- nv_debug(priv, " vdiv: %08x\n", priv->vdiv);
- if (priv->csrc == nv_clk_src_hclkm4)
- nv_debug(priv, "core: hrefm4\n");
- else
- nv_debug(priv, "core: nvpll\n");
-
- if (priv->ssrc == nv_clk_src_hclkm4)
- nv_debug(priv, "shader: hrefm4\n");
- else if (priv->ssrc == nv_clk_src_core)
- nv_debug(priv, "shader: nvpll\n");
- else
- nv_debug(priv, "shader: spll\n");
-
- if (priv->vsrc == nv_clk_src_hclkm4)
- nv_debug(priv, "vdec: 500MHz\n");
- else
- nv_debug(priv, "vdec: core\n");
-
- return 0;
-}
-
-static int
-nvaa_clock_prog(struct nouveau_clock *clk)
-{
- struct nvaa_clock_priv *priv = (void *)clk;
- struct nouveau_fifo *pfifo = nouveau_fifo(clk);
- unsigned long flags;
- u32 pllmask = 0, mast, ptherm_gate;
- int ret = -EBUSY;
-
- /* halt and idle execution engines */
- ptherm_gate = nv_mask(clk, 0x020060, 0x00070000, 0x00000000);
- nv_mask(clk, 0x002504, 0x00000001, 0x00000001);
- /* Wait until the interrupt handler is finished */
- if (!nv_wait(clk, 0x000100, 0xffffffff, 0x00000000))
- goto resume;
-
- if (pfifo)
- pfifo->pause(pfifo, &flags);
-
- if (!nv_wait(clk, 0x002504, 0x00000010, 0x00000010))
- goto resume;
- if (!nv_wait(clk, 0x00251c, 0x0000003f, 0x0000003f))
- goto resume;
-
- /* First switch to safe clocks: href */
- mast = nv_mask(clk, 0xc054, 0x03400e70, 0x03400640);
- mast &= ~0x00400e73;
- mast |= 0x03000000;
-
- switch (priv->csrc) {
- case nv_clk_src_hclkm4:
- nv_mask(clk, 0x4028, 0x00070000, priv->cctrl);
- mast |= 0x00000002;
- break;
- case nv_clk_src_core:
- nv_wr32(clk, 0x402c, priv->ccoef);
- nv_wr32(clk, 0x4028, 0x80000000 | priv->cctrl);
- nv_wr32(clk, 0x4040, priv->cpost);
- pllmask |= (0x3 << 8);
- mast |= 0x00000003;
- break;
- default:
- nv_warn(priv,"Reclocking failed: unknown core clock\n");
- goto resume;
- }
-
- switch (priv->ssrc) {
- case nv_clk_src_href:
- nv_mask(clk, 0x4020, 0x00070000, 0x00000000);
- /* mast |= 0x00000000; */
- break;
- case nv_clk_src_core:
- nv_mask(clk, 0x4020, 0x00070000, priv->sctrl);
- mast |= 0x00000020;
- break;
- case nv_clk_src_shader:
- nv_wr32(clk, 0x4024, priv->scoef);
- nv_wr32(clk, 0x4020, 0x80000000 | priv->sctrl);
- nv_wr32(clk, 0x4070, priv->spost);
- pllmask |= (0x3 << 12);
- mast |= 0x00000030;
- break;
- default:
- nv_warn(priv,"Reclocking failed: unknown sclk clock\n");
- goto resume;
- }
-
- if (!nv_wait(clk, 0x004080, pllmask, pllmask)) {
- nv_warn(priv,"Reclocking failed: unstable PLLs\n");
- goto resume;
- }
-
- switch (priv->vsrc) {
- case nv_clk_src_cclk:
- mast |= 0x00400000;
- default:
- nv_wr32(clk, 0x4600, priv->vdiv);
- }
-
- nv_wr32(clk, 0xc054, mast);
- ret = 0;
-
-resume:
- if (pfifo)
- pfifo->start(pfifo, &flags);
-
- nv_mask(clk, 0x002504, 0x00000001, 0x00000000);
- nv_wr32(clk, 0x020060, ptherm_gate);
-
- /* Disable some PLLs and dividers when unused */
- if (priv->csrc != nv_clk_src_core) {
- nv_wr32(clk, 0x4040, 0x00000000);
- nv_mask(clk, 0x4028, 0x80000000, 0x00000000);
- }
-
- if (priv->ssrc != nv_clk_src_shader) {
- nv_wr32(clk, 0x4070, 0x00000000);
- nv_mask(clk, 0x4020, 0x80000000, 0x00000000);
- }
-
- return ret;
-}
-
-static void
-nvaa_clock_tidy(struct nouveau_clock *clk)
-{
-}
-
-static struct nouveau_clocks
-nvaa_domains[] = {
- { nv_clk_src_crystal, 0xff },
- { nv_clk_src_href , 0xff },
- { nv_clk_src_core , 0xff, 0, "core", 1000 },
- { nv_clk_src_shader , 0xff, 0, "shader", 1000 },
- { nv_clk_src_vdec , 0xff, 0, "vdec", 1000 },
- { nv_clk_src_max }
-};
-
-static int
-nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvaa_clock_priv *priv;
- int ret;
-
- ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.read = nvaa_clock_read;
- priv->base.calc = nvaa_clock_calc;
- priv->base.prog = nvaa_clock_prog;
- priv->base.tidy = nvaa_clock_tidy;
- return 0;
-}
-
-struct nouveau_oclass *
-nvaa_clock_oclass = &(struct nouveau_oclass) {
- .handle = NV_SUBDEV(CLOCK, 0xaa),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvaa_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
index c310572..439d81c2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -25,408 +25,11 @@
#include <subdev/clock.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include <subdev/timer.h>
#include "pll.h"
-struct nvc0_clock_info {
- u32 freq;
- u32 ssel;
- u32 mdiv;
- u32 dsrc;
- u32 ddiv;
- u32 coef;
-};
-
struct nvc0_clock_priv {
struct nouveau_clock base;
- struct nvc0_clock_info eng[16];
-};
-
-static u32 read_div(struct nvc0_clock_priv *, int, u32, u32);
-
-static u32
-read_vco(struct nvc0_clock_priv *priv, u32 dsrc)
-{
- struct nouveau_clock *clk = &priv->base;
- u32 ssrc = nv_rd32(priv, dsrc);
- if (!(ssrc & 0x00000100))
- return clk->read(clk, nv_clk_src_sppll0);
- return clk->read(clk, nv_clk_src_sppll1);
-}
-
-static u32
-read_pll(struct nvc0_clock_priv *priv, u32 pll)
-{
- struct nouveau_clock *clk = &priv->base;
- u32 ctrl = nv_rd32(priv, pll + 0x00);
- u32 coef = nv_rd32(priv, pll + 0x04);
- u32 P = (coef & 0x003f0000) >> 16;
- u32 N = (coef & 0x0000ff00) >> 8;
- u32 M = (coef & 0x000000ff) >> 0;
- u32 sclk;
-
- if (!(ctrl & 0x00000001))
- return 0;
-
- switch (pll) {
- case 0x00e800:
- case 0x00e820:
- sclk = nv_device(priv)->crystal;
- P = 1;
- break;
- case 0x132000:
- sclk = clk->read(clk, nv_clk_src_mpllsrc);
- break;
- case 0x132020:
- sclk = clk->read(clk, nv_clk_src_mpllsrcref);
- break;
- case 0x137000:
- case 0x137020:
- case 0x137040:
- case 0x1370e0:
- sclk = read_div(priv, (pll & 0xff) / 0x20, 0x137120, 0x137140);
- break;
- default:
- return 0;
- }
-
- return sclk * N / M / P;
-}
-
-static u32
-read_div(struct nvc0_clock_priv *priv, int doff, u32 dsrc, u32 dctl)
-{
- u32 ssrc = nv_rd32(priv, dsrc + (doff * 4));
- u32 sctl = nv_rd32(priv, dctl + (doff * 4));
-
- switch (ssrc & 0x00000003) {
- case 0:
- if ((ssrc & 0x00030000) != 0x00030000)
- return nv_device(priv)->crystal;
- return 108000;
- case 2:
- return 100000;
- case 3:
- if (sctl & 0x80000000) {
- u32 sclk = read_vco(priv, dsrc + (doff * 4));
- u32 sdiv = (sctl & 0x0000003f) + 2;
- return (sclk * 2) / sdiv;
- }
-
- return read_vco(priv, dsrc + (doff * 4));
- default:
- return 0;
- }
-}
-
-static u32
-read_clk(struct nvc0_clock_priv *priv, int clk)
-{
- u32 sctl = nv_rd32(priv, 0x137250 + (clk * 4));
- u32 ssel = nv_rd32(priv, 0x137100);
- u32 sclk, sdiv;
-
- if (ssel & (1 << clk)) {
- if (clk < 7)
- sclk = read_pll(priv, 0x137000 + (clk * 0x20));
- else
- sclk = read_pll(priv, 0x1370e0);
- sdiv = ((sctl & 0x00003f00) >> 8) + 2;
- } else {
- sclk = read_div(priv, clk, 0x137160, 0x1371d0);
- sdiv = ((sctl & 0x0000003f) >> 0) + 2;
- }
-
- if (sctl & 0x80000000)
- return (sclk * 2) / sdiv;
-
- return sclk;
-}
-
-static int
-nvc0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
-{
- struct nouveau_device *device = nv_device(clk);
- struct nvc0_clock_priv *priv = (void *)clk;
-
- switch (src) {
- case nv_clk_src_crystal:
- return device->crystal;
- case nv_clk_src_href:
- return 100000;
- case nv_clk_src_sppll0:
- return read_pll(priv, 0x00e800);
- case nv_clk_src_sppll1:
- return read_pll(priv, 0x00e820);
-
- case nv_clk_src_mpllsrcref:
- return read_div(priv, 0, 0x137320, 0x137330);
- case nv_clk_src_mpllsrc:
- return read_pll(priv, 0x132020);
- case nv_clk_src_mpll:
- return read_pll(priv, 0x132000);
- case nv_clk_src_mdiv:
- return read_div(priv, 0, 0x137300, 0x137310);
- case nv_clk_src_mem:
- if (nv_rd32(priv, 0x1373f0) & 0x00000002)
- return clk->read(clk, nv_clk_src_mpll);
- return clk->read(clk, nv_clk_src_mdiv);
-
- case nv_clk_src_gpc:
- return read_clk(priv, 0x00);
- case nv_clk_src_rop:
- return read_clk(priv, 0x01);
- case nv_clk_src_hubk07:
- return read_clk(priv, 0x02);
- case nv_clk_src_hubk06:
- return read_clk(priv, 0x07);
- case nv_clk_src_hubk01:
- return read_clk(priv, 0x08);
- case nv_clk_src_copy:
- return read_clk(priv, 0x09);
- case nv_clk_src_daemon:
- return read_clk(priv, 0x0c);
- case nv_clk_src_vdec:
- return read_clk(priv, 0x0e);
- default:
- nv_error(clk, "invalid clock source %d\n", src);
- return -EINVAL;
- }
-}
-
-static u32
-calc_div(struct nvc0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
-{
- u32 div = min((ref * 2) / freq, (u32)65);
- if (div < 2)
- div = 2;
-
- *ddiv = div - 2;
- return (ref * 2) / div;
-}
-
-static u32
-calc_src(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
-{
- u32 sclk;
-
- /* use one of the fixed frequencies if possible */
- *ddiv = 0x00000000;
- switch (freq) {
- case 27000:
- case 108000:
- *dsrc = 0x00000000;
- if (freq == 108000)
- *dsrc |= 0x00030000;
- return freq;
- case 100000:
- *dsrc = 0x00000002;
- return freq;
- default:
- *dsrc = 0x00000003;
- break;
- }
-
- /* otherwise, calculate the closest divider */
- sclk = read_vco(priv, 0x137160 + (clk * 4));
- if (clk < 7)
- sclk = calc_div(priv, clk, sclk, freq, ddiv);
- return sclk;
-}
-
-static u32
-calc_pll(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *coef)
-{
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll limits;
- int N, M, P, ret;
-
- ret = nvbios_pll_parse(bios, 0x137000 + (clk * 0x20), &limits);
- if (ret)
- return 0;
-
- limits.refclk = read_div(priv, clk, 0x137120, 0x137140);
- if (!limits.refclk)
- return 0;
-
- ret = nva3_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P);
- if (ret <= 0)
- return 0;
-
- *coef = (P << 16) | (N << 8) | M;
- return ret;
-}
-
-static int
-calc_clk(struct nvc0_clock_priv *priv,
- struct nouveau_cstate *cstate, int clk, int dom)
-{
- struct nvc0_clock_info *info = &priv->eng[clk];
- u32 freq = cstate->domain[dom];
- u32 src0, div0, div1D, div1P = 0;
- u32 clk0, clk1 = 0;
-
- /* invalid clock domain */
- if (!freq)
- return 0;
-
- /* first possible path, using only dividers */
- clk0 = calc_src(priv, clk, freq, &src0, &div0);
- clk0 = calc_div(priv, clk, clk0, freq, &div1D);
-
- /* see if we can get any closer using PLLs */
- if (clk0 != freq && (0x00004387 & (1 << clk))) {
- if (clk <= 7)
- clk1 = calc_pll(priv, clk, freq, &info->coef);
- else
- clk1 = cstate->domain[nv_clk_src_hubk06];
- clk1 = calc_div(priv, clk, clk1, freq, &div1P);
- }
-
- /* select the method which gets closest to target freq */
- if (abs((int)freq - clk0) <= abs((int)freq - clk1)) {
- info->dsrc = src0;
- if (div0) {
- info->ddiv |= 0x80000000;
- info->ddiv |= div0 << 8;
- info->ddiv |= div0;
- }
- if (div1D) {
- info->mdiv |= 0x80000000;
- info->mdiv |= div1D;
- }
- info->ssel = info->coef = 0;
- info->freq = clk0;
- } else {
- if (div1P) {
- info->mdiv |= 0x80000000;
- info->mdiv |= div1P << 8;
- }
- info->ssel = (1 << clk);
- info->freq = clk1;
- }
-
- return 0;
-}
-
-static int
-nvc0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
-{
- struct nvc0_clock_priv *priv = (void *)clk;
- int ret;
-
- if ((ret = calc_clk(priv, cstate, 0x00, nv_clk_src_gpc)) ||
- (ret = calc_clk(priv, cstate, 0x01, nv_clk_src_rop)) ||
- (ret = calc_clk(priv, cstate, 0x02, nv_clk_src_hubk07)) ||
- (ret = calc_clk(priv, cstate, 0x07, nv_clk_src_hubk06)) ||
- (ret = calc_clk(priv, cstate, 0x08, nv_clk_src_hubk01)) ||
- (ret = calc_clk(priv, cstate, 0x09, nv_clk_src_copy)) ||
- (ret = calc_clk(priv, cstate, 0x0c, nv_clk_src_daemon)) ||
- (ret = calc_clk(priv, cstate, 0x0e, nv_clk_src_vdec)))
- return ret;
-
- return 0;
-}
-
-static void
-nvc0_clock_prog_0(struct nvc0_clock_priv *priv, int clk)
-{
- struct nvc0_clock_info *info = &priv->eng[clk];
- if (clk < 7 && !info->ssel) {
- nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv);
- nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc);
- }
-}
-
-static void
-nvc0_clock_prog_1(struct nvc0_clock_priv *priv, int clk)
-{
- nv_mask(priv, 0x137100, (1 << clk), 0x00000000);
- nv_wait(priv, 0x137100, (1 << clk), 0x00000000);
-}
-
-static void
-nvc0_clock_prog_2(struct nvc0_clock_priv *priv, int clk)
-{
- struct nvc0_clock_info *info = &priv->eng[clk];
- const u32 addr = 0x137000 + (clk * 0x20);
- if (clk <= 7) {
- nv_mask(priv, addr + 0x00, 0x00000004, 0x00000000);
- nv_mask(priv, addr + 0x00, 0x00000001, 0x00000000);
- if (info->coef) {
- nv_wr32(priv, addr + 0x04, info->coef);
- nv_mask(priv, addr + 0x00, 0x00000001, 0x00000001);
- nv_wait(priv, addr + 0x00, 0x00020000, 0x00020000);
- nv_mask(priv, addr + 0x00, 0x00020004, 0x00000004);
- }
- }
-}
-
-static void
-nvc0_clock_prog_3(struct nvc0_clock_priv *priv, int clk)
-{
- struct nvc0_clock_info *info = &priv->eng[clk];
- if (info->ssel) {
- nv_mask(priv, 0x137100, (1 << clk), info->ssel);
- nv_wait(priv, 0x137100, (1 << clk), info->ssel);
- }
-}
-
-static void
-nvc0_clock_prog_4(struct nvc0_clock_priv *priv, int clk)
-{
- struct nvc0_clock_info *info = &priv->eng[clk];
- nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv);
-}
-
-static int
-nvc0_clock_prog(struct nouveau_clock *clk)
-{
- struct nvc0_clock_priv *priv = (void *)clk;
- struct {
- void (*exec)(struct nvc0_clock_priv *, int);
- } stage[] = {
- { nvc0_clock_prog_0 }, /* div programming */
- { nvc0_clock_prog_1 }, /* select div mode */
- { nvc0_clock_prog_2 }, /* (maybe) program pll */
- { nvc0_clock_prog_3 }, /* (maybe) select pll mode */
- { nvc0_clock_prog_4 }, /* final divider */
- };
- int i, j;
-
- for (i = 0; i < ARRAY_SIZE(stage); i++) {
- for (j = 0; j < ARRAY_SIZE(priv->eng); j++) {
- if (!priv->eng[j].freq)
- continue;
- stage[i].exec(priv, j);
- }
- }
-
- return 0;
-}
-
-static void
-nvc0_clock_tidy(struct nouveau_clock *clk)
-{
- struct nvc0_clock_priv *priv = (void *)clk;
- memset(priv->eng, 0x00, sizeof(priv->eng));
-}
-
-static struct nouveau_clocks
-nvc0_domain[] = {
- { nv_clk_src_crystal, 0xff },
- { nv_clk_src_href , 0xff },
- { nv_clk_src_hubk06 , 0x00 },
- { nv_clk_src_hubk01 , 0x01 },
- { nv_clk_src_copy , 0x02 },
- { nv_clk_src_gpc , 0x03, 0, "core", 2000 },
- { nv_clk_src_rop , 0x04 },
- { nv_clk_src_mem , 0x05, 0, "memory", 1000 },
- { nv_clk_src_vdec , 0x06 },
- { nv_clk_src_daemon , 0x0a },
- { nv_clk_src_hubk07 , 0x0b },
- { nv_clk_src_max }
};
static int
@@ -437,15 +40,12 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nvc0_clock_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, &priv);
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.read = nvc0_clock_read;
- priv->base.calc = nvc0_clock_calc;
- priv->base.prog = nvc0_clock_prog;
- priv->base.tidy = nvc0_clock_tidy;
+ priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c
deleted file mode 100644
index 4c62e84..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * 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/clock.h>
-#include <subdev/timer.h>
-#include <subdev/bios.h>
-#include <subdev/bios/pll.h>
-
-#include "pll.h"
-
-struct nve0_clock_info {
- u32 freq;
- u32 ssel;
- u32 mdiv;
- u32 dsrc;
- u32 ddiv;
- u32 coef;
-};
-
-struct nve0_clock_priv {
- struct nouveau_clock base;
- struct nve0_clock_info eng[16];
-};
-
-static u32 read_div(struct nve0_clock_priv *, int, u32, u32);
-static u32 read_pll(struct nve0_clock_priv *, u32);
-
-static u32
-read_vco(struct nve0_clock_priv *priv, u32 dsrc)
-{
- u32 ssrc = nv_rd32(priv, dsrc);
- if (!(ssrc & 0x00000100))
- return read_pll(priv, 0x00e800);
- return read_pll(priv, 0x00e820);
-}
-
-static u32
-read_pll(struct nve0_clock_priv *priv, u32 pll)
-{
- u32 ctrl = nv_rd32(priv, pll + 0x00);
- u32 coef = nv_rd32(priv, pll + 0x04);
- u32 P = (coef & 0x003f0000) >> 16;
- u32 N = (coef & 0x0000ff00) >> 8;
- u32 M = (coef & 0x000000ff) >> 0;
- u32 sclk;
- u16 fN = 0xf000;
-
- if (!(ctrl & 0x00000001))
- return 0;
-
- switch (pll) {
- case 0x00e800:
- case 0x00e820:
- sclk = nv_device(priv)->crystal;
- P = 1;
- break;
- case 0x132000:
- sclk = read_pll(priv, 0x132020);
- P = (coef & 0x10000000) ? 2 : 1;
- break;
- case 0x132020:
- sclk = read_div(priv, 0, 0x137320, 0x137330);
- fN = nv_rd32(priv, pll + 0x10) >> 16;
- break;
- case 0x137000:
- case 0x137020:
- case 0x137040:
- case 0x1370e0:
- sclk = read_div(priv, (pll & 0xff) / 0x20, 0x137120, 0x137140);
- break;
- default:
- return 0;
- }
-
- if (P == 0)
- P = 1;
-
- sclk = (sclk * N) + (((u16)(fN + 4096) * sclk) >> 13);
- return sclk / (M * P);
-}
-
-static u32
-read_div(struct nve0_clock_priv *priv, int doff, u32 dsrc, u32 dctl)
-{
- u32 ssrc = nv_rd32(priv, dsrc + (doff * 4));
- u32 sctl = nv_rd32(priv, dctl + (doff * 4));
-
- switch (ssrc & 0x00000003) {
- case 0:
- if ((ssrc & 0x00030000) != 0x00030000)
- return nv_device(priv)->crystal;
- return 108000;
- case 2:
- return 100000;
- case 3:
- if (sctl & 0x80000000) {
- u32 sclk = read_vco(priv, dsrc + (doff * 4));
- u32 sdiv = (sctl & 0x0000003f) + 2;
- return (sclk * 2) / sdiv;
- }
-
- return read_vco(priv, dsrc + (doff * 4));
- default:
- return 0;
- }
-}
-
-static u32
-read_mem(struct nve0_clock_priv *priv)
-{
- switch (nv_rd32(priv, 0x1373f4) & 0x0000000f) {
- case 1: return read_pll(priv, 0x132020);
- case 2: return read_pll(priv, 0x132000);
- default:
- return 0;
- }
-}
-
-static u32
-read_clk(struct nve0_clock_priv *priv, int clk)
-{
- u32 sctl = nv_rd32(priv, 0x137250 + (clk * 4));
- u32 sclk, sdiv;
-
- if (clk < 7) {
- u32 ssel = nv_rd32(priv, 0x137100);
- if (ssel & (1 << clk)) {
- sclk = read_pll(priv, 0x137000 + (clk * 0x20));
- sdiv = 1;
- } else {
- sclk = read_div(priv, clk, 0x137160, 0x1371d0);
- sdiv = 0;
- }
- } else {
- u32 ssrc = nv_rd32(priv, 0x137160 + (clk * 0x04));
- if ((ssrc & 0x00000003) == 0x00000003) {
- sclk = read_div(priv, clk, 0x137160, 0x1371d0);
- if (ssrc & 0x00000100) {
- if (ssrc & 0x40000000)
- sclk = read_pll(priv, 0x1370e0);
- sdiv = 1;
- } else {
- sdiv = 0;
- }
- } else {
- sclk = read_div(priv, clk, 0x137160, 0x1371d0);
- sdiv = 0;
- }
- }
-
- if (sctl & 0x80000000) {
- if (sdiv)
- sdiv = ((sctl & 0x00003f00) >> 8) + 2;
- else
- sdiv = ((sctl & 0x0000003f) >> 0) + 2;
- return (sclk * 2) / sdiv;
- }
-
- return sclk;
-}
-
-static int
-nve0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
-{
- struct nouveau_device *device = nv_device(clk);
- struct nve0_clock_priv *priv = (void *)clk;
-
- switch (src) {
- case nv_clk_src_crystal:
- return device->crystal;
- case nv_clk_src_href:
- return 100000;
- case nv_clk_src_mem:
- return read_mem(priv);
- case nv_clk_src_gpc:
- return read_clk(priv, 0x00);
- case nv_clk_src_rop:
- return read_clk(priv, 0x01);
- case nv_clk_src_hubk07:
- return read_clk(priv, 0x02);
- case nv_clk_src_hubk06:
- return read_clk(priv, 0x07);
- case nv_clk_src_hubk01:
- return read_clk(priv, 0x08);
- case nv_clk_src_daemon:
- return read_clk(priv, 0x0c);
- case nv_clk_src_vdec:
- return read_clk(priv, 0x0e);
- default:
- nv_error(clk, "invalid clock source %d\n", src);
- return -EINVAL;
- }
-}
-
-static u32
-calc_div(struct nve0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
-{
- u32 div = min((ref * 2) / freq, (u32)65);
- if (div < 2)
- div = 2;
-
- *ddiv = div - 2;
- return (ref * 2) / div;
-}
-
-static u32
-calc_src(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
-{
- u32 sclk;
-
- /* use one of the fixed frequencies if possible */
- *ddiv = 0x00000000;
- switch (freq) {
- case 27000:
- case 108000:
- *dsrc = 0x00000000;
- if (freq == 108000)
- *dsrc |= 0x00030000;
- return freq;
- case 100000:
- *dsrc = 0x00000002;
- return freq;
- default:
- *dsrc = 0x00000003;
- break;
- }
-
- /* otherwise, calculate the closest divider */
- sclk = read_vco(priv, 0x137160 + (clk * 4));
- if (clk < 7)
- sclk = calc_div(priv, clk, sclk, freq, ddiv);
- return sclk;
-}
-
-static u32
-calc_pll(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *coef)
-{
- struct nouveau_bios *bios = nouveau_bios(priv);
- struct nvbios_pll limits;
- int N, M, P, ret;
-
- ret = nvbios_pll_parse(bios, 0x137000 + (clk * 0x20), &limits);
- if (ret)
- return 0;
-
- limits.refclk = read_div(priv, clk, 0x137120, 0x137140);
- if (!limits.refclk)
- return 0;
-
- ret = nva3_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P);
- if (ret <= 0)
- return 0;
-
- *coef = (P << 16) | (N << 8) | M;
- return ret;
-}
-
-static int
-calc_clk(struct nve0_clock_priv *priv,
- struct nouveau_cstate *cstate, int clk, int dom)
-{
- struct nve0_clock_info *info = &priv->eng[clk];
- u32 freq = cstate->domain[dom];
- u32 src0, div0, div1D, div1P = 0;
- u32 clk0, clk1 = 0;
-
- /* invalid clock domain */
- if (!freq)
- return 0;
-
- /* first possible path, using only dividers */
- clk0 = calc_src(priv, clk, freq, &src0, &div0);
- clk0 = calc_div(priv, clk, clk0, freq, &div1D);
-
- /* see if we can get any closer using PLLs */
- if (clk0 != freq && (0x0000ff87 & (1 << clk))) {
- if (clk <= 7)
- clk1 = calc_pll(priv, clk, freq, &info->coef);
- else
- clk1 = cstate->domain[nv_clk_src_hubk06];
- clk1 = calc_div(priv, clk, clk1, freq, &div1P);
- }
-
- /* select the method which gets closest to target freq */
- if (abs((int)freq - clk0) <= abs((int)freq - clk1)) {
- info->dsrc = src0;
- if (div0) {
- info->ddiv |= 0x80000000;
- info->ddiv |= div0 << 8;
- info->ddiv |= div0;
- }
- if (div1D) {
- info->mdiv |= 0x80000000;
- info->mdiv |= div1D;
- }
- info->ssel = 0;
- info->freq = clk0;
- } else {
- if (div1P) {
- info->mdiv |= 0x80000000;
- info->mdiv |= div1P << 8;
- }
- info->ssel = (1 << clk);
- info->dsrc = 0x40000100;
- info->freq = clk1;
- }
-
- return 0;
-}
-
-static int
-nve0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
-{
- struct nve0_clock_priv *priv = (void *)clk;
- int ret;
-
- if ((ret = calc_clk(priv, cstate, 0x00, nv_clk_src_gpc)) ||
- (ret = calc_clk(priv, cstate, 0x01, nv_clk_src_rop)) ||
- (ret = calc_clk(priv, cstate, 0x02, nv_clk_src_hubk07)) ||
- (ret = calc_clk(priv, cstate, 0x07, nv_clk_src_hubk06)) ||
- (ret = calc_clk(priv, cstate, 0x08, nv_clk_src_hubk01)) ||
- (ret = calc_clk(priv, cstate, 0x0c, nv_clk_src_daemon)) ||
- (ret = calc_clk(priv, cstate, 0x0e, nv_clk_src_vdec)))
- return ret;
-
- return 0;
-}
-
-static void
-nve0_clock_prog_0(struct nve0_clock_priv *priv, int clk)
-{
- struct nve0_clock_info *info = &priv->eng[clk];
- if (!info->ssel) {
- nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv);
- nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc);
- }
-}
-
-static void
-nve0_clock_prog_1_0(struct nve0_clock_priv *priv, int clk)
-{
- nv_mask(priv, 0x137100, (1 << clk), 0x00000000);
- nv_wait(priv, 0x137100, (1 << clk), 0x00000000);
-}
-
-static void
-nve0_clock_prog_1_1(struct nve0_clock_priv *priv, int clk)
-{
- nv_mask(priv, 0x137160 + (clk * 0x04), 0x00000100, 0x00000000);
-}
-
-static void
-nve0_clock_prog_2(struct nve0_clock_priv *priv, int clk)
-{
- struct nve0_clock_info *info = &priv->eng[clk];
- const u32 addr = 0x137000 + (clk * 0x20);
- nv_mask(priv, addr + 0x00, 0x00000004, 0x00000000);
- nv_mask(priv, addr + 0x00, 0x00000001, 0x00000000);
- if (info->coef) {
- nv_wr32(priv, addr + 0x04, info->coef);
- nv_mask(priv, addr + 0x00, 0x00000001, 0x00000001);
- nv_wait(priv, addr + 0x00, 0x00020000, 0x00020000);
- nv_mask(priv, addr + 0x00, 0x00020004, 0x00000004);
- }
-}
-
-static void
-nve0_clock_prog_3(struct nve0_clock_priv *priv, int clk)
-{
- struct nve0_clock_info *info = &priv->eng[clk];
- nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv);
-}
-
-static void
-nve0_clock_prog_4_0(struct nve0_clock_priv *priv, int clk)
-{
- struct nve0_clock_info *info = &priv->eng[clk];
- if (info->ssel) {
- nv_mask(priv, 0x137100, (1 << clk), info->ssel);
- nv_wait(priv, 0x137100, (1 << clk), info->ssel);
- }
-}
-
-static void
-nve0_clock_prog_4_1(struct nve0_clock_priv *priv, int clk)
-{
- struct nve0_clock_info *info = &priv->eng[clk];
- if (info->ssel) {
- nv_mask(priv, 0x137160 + (clk * 0x04), 0x40000000, 0x40000000);
- nv_mask(priv, 0x137160 + (clk * 0x04), 0x00000100, 0x00000100);
- }
-}
-
-static int
-nve0_clock_prog(struct nouveau_clock *clk)
-{
- struct nve0_clock_priv *priv = (void *)clk;
- struct {
- u32 mask;
- void (*exec)(struct nve0_clock_priv *, int);
- } stage[] = {
- { 0x007f, nve0_clock_prog_0 }, /* div programming */
- { 0x007f, nve0_clock_prog_1_0 }, /* select div mode */
- { 0xff80, nve0_clock_prog_1_1 },
- { 0x00ff, nve0_clock_prog_2 }, /* (maybe) program pll */
- { 0xff80, nve0_clock_prog_3 }, /* final divider */
- { 0x007f, nve0_clock_prog_4_0 }, /* (maybe) select pll mode */
- { 0xff80, nve0_clock_prog_4_1 },
- };
- int i, j;
-
- for (i = 0; i < ARRAY_SIZE(stage); i++) {
- for (j = 0; j < ARRAY_SIZE(priv->eng); j++) {
- if (!(stage[i].mask & (1 << j)))
- continue;
- if (!priv->eng[j].freq)
- continue;
- stage[i].exec(priv, j);
- }
- }
-
- return 0;
-}
-
-static void
-nve0_clock_tidy(struct nouveau_clock *clk)
-{
- struct nve0_clock_priv *priv = (void *)clk;
- memset(priv->eng, 0x00, sizeof(priv->eng));
-}
-
-static struct nouveau_clocks
-nve0_domain[] = {
- { nv_clk_src_crystal, 0xff },
- { nv_clk_src_href , 0xff },
- { nv_clk_src_gpc , 0x00, NVKM_CLK_DOM_FLAG_CORE, "core", 2000 },
- { nv_clk_src_hubk07 , 0x01, NVKM_CLK_DOM_FLAG_CORE },
- { nv_clk_src_rop , 0x02, NVKM_CLK_DOM_FLAG_CORE },
- { nv_clk_src_mem , 0x03, 0, "memory", 1000 },
- { nv_clk_src_hubk06 , 0x04, NVKM_CLK_DOM_FLAG_CORE },
- { nv_clk_src_hubk01 , 0x05 },
- { nv_clk_src_vdec , 0x06 },
- { nv_clk_src_daemon , 0x07 },
- { nv_clk_src_max }
-};
-
-static int
-nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nve0_clock_priv *priv;
- int ret;
-
- ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.read = nve0_clock_read;
- priv->base.calc = nve0_clock_calc;
- priv->base.prog = nve0_clock_prog;
- priv->base.tidy = nve0_clock_tidy;
- return 0;
-}
-
-struct nouveau_oclass
-nve0_clock_oclass = {
- .handle = NV_SUBDEV(CLOCK, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
index b47d543..cf1ed0d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
@@ -38,7 +38,7 @@ getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
* "clk" parameter in kHz
* returns calculated clock
*/
- struct nouveau_bios *bios = nouveau_bios(subdev);
+ 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;
@@ -54,21 +54,18 @@ getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
/* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
/* possibly correlated with introduction of 27MHz crystal */
- if (bios->version.major < 0x60) {
- int cv = bios->version.chip;
- if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
- if (clk > 250000)
- maxM = 6;
- if (clk > 340000)
- maxM = 2;
- } else if (cv < 0x40) {
- if (clk > 150000)
- maxM = 6;
- if (clk > 200000)
- maxM = 4;
- if (clk > 340000)
- maxM = 2;
- }
+ if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
+ if (clk > 250000)
+ maxM = 6;
+ if (clk > 340000)
+ maxM = 2;
+ } else if (cv < 0x40) {
+ if (clk > 150000)
+ maxM = 6;
+ if (clk > 200000)
+ maxM = 4;
+ if (clk > 340000)
+ maxM = 2;
}
P = 1 << maxP;
@@ -230,12 +227,10 @@ nv04_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info, u32 freq,
{
int ret;
- if (!info->vco2.max_freq || !N2) {
+ if (!info->vco2.max_freq) {
ret = getMNP_single(subdev, info, freq, N1, M1, P);
- if (N2) {
- *N2 = 1;
- *M2 = 1;
- }
+ *N2 = 1;
+ *M2 = 1;
} else {
ret = getMNP_double(subdev, info, freq, N1, M1, N2, M2, P);
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
index 8eca457..2fe1f71 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
@@ -45,7 +45,6 @@ nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
lM = max(lM, (int)info->vco1.min_m);
hM = (info->refclk + info->vco1.min_inputfreq) / info->vco1.min_inputfreq;
hM = min(hM, (int)info->vco1.max_m);
- lM = min(lM, hM);
for (M = lM; M <= hM; M++) {
u32 tmp = freq * *P * M;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h b/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h
deleted file mode 100644
index fb33f06..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __NVKM_CLK_SEQ_H__
-#define __NVKM_CLK_SEQ_H__
-
-#include <subdev/bus.h>
-#include <subdev/bus/hwsq.h>
-
-#define clk_init(s,p) hwsq_init(&(s)->base, (p))
-#define clk_exec(s,e) hwsq_exec(&(s)->base, (e))
-#define clk_have(s,r) ((s)->r_##r.addr != 0x000000)
-#define clk_rd32(s,r) hwsq_rd32(&(s)->base, &(s)->r_##r)
-#define clk_wr32(s,r,d) hwsq_wr32(&(s)->base, &(s)->r_##r, (d))
-#define clk_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d))
-#define clk_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
-#define clk_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
-#define clk_nsec(s,n) hwsq_nsec(&(s)->base, (n))
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
index 27c8235..b22357d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
@@ -168,8 +168,7 @@ setPLL_single(struct nouveau_devinit *devinit, u32 reg,
/* downclock -- write new NM first */
nv_wr32(devinit, reg, (oldpll & 0xffff0000) | pv->NM1);
- if ((chip_version < 0x17 || chip_version == 0x1a) &&
- chip_version != 0x11)
+ if (chip_version < 0x17 && chip_version != 0x11)
/* wait a bit on older chips */
msleep(64);
nv_rd32(devinit, reg);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
index 8d274db..463b08f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
@@ -38,18 +38,12 @@ static void
nv10_devinit_meminit(struct nouveau_devinit *devinit)
{
struct nv10_devinit_priv *priv = (void *)devinit;
- static const int mem_width[] = { 0x10, 0x00, 0x20 };
- int mem_width_count;
+ const int mem_width[] = { 0x10, 0x00, 0x20 };
+ const int mem_width_count = nv_device(priv)->chipset >= 0x17 ? 3 : 2;
uint32_t patt = 0xdeadbeef;
struct io_mapping *fb;
int i, j, k;
- if (nv_device(priv)->card_type >= NV_11 &&
- nv_device(priv)->chipset >= 0x17)
- mem_width_count = 3;
- else
- mem_width_count = 2;
-
/* Map the framebuffer aperture */
fb = fbmem_init(nv_device(priv)->pdev);
if (!fb) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
index f009d8a..821cd75 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
@@ -22,10 +22,9 @@
* Authors: Ben Skeggs
*/
-#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-
-#include "priv.h"
+#include "subdev/fb.h"
+#include "subdev/bios.h"
+#include "subdev/bios/bit.h"
int
nouveau_fb_bios_memtype(struct nouveau_bios *bios)
@@ -107,9 +106,9 @@ _nouveau_fb_dtor(struct nouveau_object *object)
int
nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+ struct nouveau_oclass *oclass, struct nouveau_oclass *ramcls,
+ int length, void **pobject)
{
- struct nouveau_fb_impl *impl = (void *)oclass;
static const char *name[] = {
[NV_MEM_TYPE_UNKNOWN] = "unknown",
[NV_MEM_TYPE_STOLEN ] = "stolen system memory",
@@ -133,10 +132,8 @@ nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- pfb->memtype_valid = impl->memtype;
-
ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb),
- impl->ram, NULL, 0, &ram);
+ ramcls, NULL, 0, &ram);
if (ret) {
nv_fatal(pfb, "error detecting memory configuration!!\n");
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
deleted file mode 100644
index 34f9605..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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 <bskeggs@redhat.com>
- */
-
-#include <subdev/bios.h>
-#include "priv.h"
-
-int
-nouveau_gddr5_calc(struct nouveau_ram *ram)
-{
- struct nouveau_bios *bios = nouveau_bios(ram);
- int pd, lf, xd, vh, vr, vo;
- int WL, CL, WR, at, dt, ds;
- int rq = ram->freq < 1000000; /* XXX */
-
- switch (!!ram->ramcfg.data * ram->ramcfg.version) {
- case 0x11:
- pd = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x80) >> 7;
- lf = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x40) >> 6;
- xd = !(nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x20);
- vh = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x10) >> 4;
- vr = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x04) >> 2;
- vo = nv_ro08(bios, ram->ramcfg.data + 0x06) & 0xff;
- break;
- default:
- return -ENOSYS;
- }
-
- switch (!!ram->timing.data * ram->timing.version) {
- case 0x20:
- WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
- CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
- WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
- at = (nv_ro08(bios, ram->timing.data + 0x2e) & 0xc0) >> 6;
- dt = nv_ro08(bios, ram->timing.data + 0x2e) & 0x03;
- ds = nv_ro08(bios, ram->timing.data + 0x2f) & 0x03;
- break;
- default:
- return -ENOSYS;
- }
-
- if (WL < 1 || WL > 7 || CL < 5 || CL > 36 || WR < 4 || WR > 35)
- return -EINVAL;
- CL -= 5;
- WR -= 4;
-
- ram->mr[0] &= ~0xf7f;
- ram->mr[0] |= (WR & 0x0f) << 8;
- ram->mr[0] |= (CL & 0x0f) << 3;
- ram->mr[0] |= (WL & 0x07) << 0;
-
- ram->mr[1] &= ~0x0bf;
- ram->mr[1] |= (xd & 0x01) << 7;
- ram->mr[1] |= (at & 0x03) << 4;
- ram->mr[1] |= (dt & 0x03) << 2;
- ram->mr[1] |= (ds & 0x03) << 0;
-
- ram->mr[3] &= ~0x020;
- ram->mr[3] |= (rq & 0x01) << 5;
-
- if (!vo)
- vo = (ram->mr[6] & 0xff0) >> 4;
- if (ram->mr[6] & 0x001)
- pd = 1; /* binary driver does this.. bug? */
- ram->mr[6] &= ~0xff1;
- ram->mr[6] |= (vo & 0xff) << 4;
- ram->mr[6] |= (pd & 0x01) << 0;
-
- if (!(ram->mr[7] & 0x100))
- vr = 0; /* binary driver does this.. bug? */
- ram->mr[7] &= ~0x188;
- ram->mr[7] |= (vr & 0x01) << 8;
- ram->mr[7] |= (vh & 0x01) << 7;
- ram->mr[7] |= (lf & 0x01) << 3;
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
index 8309fe3..1f103c7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
@@ -22,10 +22,14 @@
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
#define NV04_PFB_CFG0 0x00100200
+struct nv04_fb_priv {
+ struct nouveau_fb base;
+};
+
bool
nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
{
@@ -53,37 +57,30 @@ nv04_fb_init(struct nouveau_object *object)
return 0;
}
-int
+static int
nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv04_fb_impl *impl = (void *)oclass;
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.tile.regions = impl->tile.regions;
- priv->base.tile.init = impl->tile.init;
- priv->base.tile.comp = impl->tile.comp;
- priv->base.tile.fini = impl->tile.fini;
- priv->base.tile.prog = impl->tile.prog;
+ priv->base.memtype_valid = nv04_fb_memtype_valid;
return 0;
}
-struct nouveau_oclass *
-nv04_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x04),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass
+nv04_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv04_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv04_ram_oclass,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h
deleted file mode 100644
index 06ce71f..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __NVKM_FB_NV04_H__
-#define __NVKM_FB_NV04_H__
-
-#include "priv.h"
-
-struct nv04_fb_priv {
- struct nouveau_fb base;
-};
-
-int nv04_fb_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-struct nv04_fb_impl {
- struct nouveau_fb_impl base;
- struct {
- int regions;
- void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
- void (*comp)(struct nouveau_fb *, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *);
- void (*fini)(struct nouveau_fb *, int i,
- struct nouveau_fb_tile *);
- void (*prog)(struct nouveau_fb *, int i,
- struct nouveau_fb_tile *);
- } tile;
-};
-
-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 *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
index ffb7ec6..be069b5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv10_fb_priv {
+ struct nouveau_fb base;
+};
void
nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
@@ -53,19 +57,34 @@ nv10_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
nv_rd32(pfb, 0x100240 + (i * 0x10));
}
-struct nouveau_oclass *
-nv10_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x10),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv10_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv10_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv10_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = _nouveau_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv10_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv10_fb_tile_init,
- .tile.fini = nv10_fb_tile_fini,
- .tile.prog = nv10_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
index 9159a5c..57a2af0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
@@ -24,21 +24,40 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
-struct nouveau_oclass *
-nv1a_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x1a),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+struct nv1a_fb_priv {
+ struct nouveau_fb base;
+};
+
+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)
+{
+ struct nv1a_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv1a_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x1a),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv1a_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = _nouveau_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv10_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv10_fb_tile_init,
- .tile.fini = nv10_fb_tile_fini,
- .tile.prog = nv10_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
index f003c1b..b18c4e6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv20_fb_priv {
+ struct nouveau_fb base;
+};
void
nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
@@ -76,20 +80,35 @@ nv20_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
nv_wr32(pfb, 0x100300 + (i * 0x04), tile->zcomp);
}
-struct nouveau_oclass *
-nv20_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x20),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv20_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv20_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x20),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv20_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = _nouveau_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv20_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv20_fb_tile_init,
- .tile.comp = nv20_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv20_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
index f34f422..32ccabf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv25_fb_priv {
+ struct nouveau_fb base;
+};
static void
nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
@@ -42,20 +46,35 @@ nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
}
-struct nouveau_oclass *
-nv25_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x25),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv25_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv25_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv25_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x25),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv25_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = _nouveau_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv20_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv20_fb_tile_init,
- .tile.comp = nv25_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv20_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
index 69093f7..bef756d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv30_fb_priv {
+ struct nouveau_fb base;
+};
void
nv30_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
@@ -63,7 +67,7 @@ nv30_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
static int
-calc_bias(struct nv04_fb_priv *priv, int k, int i, int j)
+calc_bias(struct nv30_fb_priv *priv, int k, int i, int j)
{
struct nouveau_device *device = nv_device(priv);
int b = (device->chipset > 0x30 ?
@@ -74,7 +78,7 @@ calc_bias(struct nv04_fb_priv *priv, int k, int i, int j)
}
static int
-calc_ref(struct nv04_fb_priv *priv, int l, int k, int i)
+calc_ref(struct nv30_fb_priv *priv, int l, int k, int i)
{
int j, x = 0;
@@ -91,7 +95,7 @@ int
nv30_fb_init(struct nouveau_object *object)
{
struct nouveau_device *device = nv_device(object);
- struct nv04_fb_priv *priv = (void *)object;
+ struct nv30_fb_priv *priv = (void *)object;
int ret, i, j;
ret = nouveau_fb_init(&priv->base);
@@ -120,20 +124,35 @@ nv30_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv30_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x30),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv30_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv30_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv30_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x30),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv30_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv30_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv20_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv30_fb_tile_init,
- .tile.comp = nv30_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv20_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
index 161b06e..097d8e3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv35_fb_priv {
+ struct nouveau_fb base;
+};
static void
nv35_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
@@ -43,20 +47,35 @@ nv35_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
}
-struct nouveau_oclass *
-nv35_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x35),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv35_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv35_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv35_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x35),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv35_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv30_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv20_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv30_fb_tile_init,
- .tile.comp = nv35_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv20_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
index 2dd3d0a..9d6d9df 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv36_fb_priv {
+ struct nouveau_fb base;
+};
static void
nv36_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
@@ -43,20 +47,35 @@ nv36_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
}
-struct nouveau_oclass *
-nv36_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x36),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv36_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv36_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv36_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x36),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv36_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv30_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv20_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv30_fb_tile_init,
- .tile.comp = nv36_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv20_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
index 95a115a..33b4393 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv40_fb_priv {
+ struct nouveau_fb base;
+};
void
nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
@@ -46,7 +50,7 @@ nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
static int
nv40_fb_init(struct nouveau_object *object)
{
- struct nv04_fb_priv *priv = (void *)object;
+ struct nv40_fb_priv *priv = (void *)object;
int ret;
ret = nouveau_fb_init(&priv->base);
@@ -57,20 +61,36 @@ nv40_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv40_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x40),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv40_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv40_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+
+struct nouveau_oclass
+nv40_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv40_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv40_ram_oclass,
- .tile.regions = 8,
- .tile.init = nv30_fb_tile_init,
- .tile.comp = nv40_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv20_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h
deleted file mode 100644
index 581f808..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __NVKM_FB_NV40_H__
-#define __NVKM_FB_NV40_H__
-
-#include "priv.h"
-
-struct nv40_ram {
- struct nouveau_ram base;
- u32 ctrl;
- u32 coef;
-};
-
-
-int nv40_ram_calc(struct nouveau_fb *, u32);
-int nv40_ram_prog(struct nouveau_fb *);
-void nv40_ram_tidy(struct nouveau_fb *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
index b239a86..02cd837 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv41_fb_priv {
+ struct nouveau_fb base;
+};
void
nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
@@ -39,7 +43,7 @@ nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
int
nv41_fb_init(struct nouveau_object *object)
{
- struct nv04_fb_priv *priv = (void *)object;
+ struct nv41_fb_priv *priv = (void *)object;
int ret;
ret = nouveau_fb_init(&priv->base);
@@ -50,20 +54,36 @@ nv41_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv41_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x41),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv41_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv41_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+
+struct nouveau_oclass
+nv41_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x41),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv41_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv41_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv41_ram_oclass,
- .tile.regions = 12,
- .tile.init = nv30_fb_tile_init,
- .tile.comp = nv40_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv41_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
index d847820..c5246c2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv44_fb_priv {
+ struct nouveau_fb base;
+};
static void
nv44_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
@@ -48,7 +52,7 @@ nv44_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
int
nv44_fb_init(struct nouveau_object *object)
{
- struct nv04_fb_priv *priv = (void *)object;
+ struct nv44_fb_priv *priv = (void *)object;
int ret;
ret = nouveau_fb_init(&priv->base);
@@ -60,19 +64,35 @@ nv44_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv44_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x44),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv44_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv44_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+
+struct nouveau_oclass
+nv44_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x44),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv44_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv44_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv44_ram_oclass,
- .tile.regions = 12,
- .tile.init = nv44_fb_tile_init,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv44_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
index a5b7751..e2b5790 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
@@ -24,7 +24,11 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
+
+struct nv46_fb_priv {
+ struct nouveau_fb base;
+};
void
nv46_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
@@ -40,19 +44,35 @@ nv46_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
tile->pitch = pitch;
}
-struct nouveau_oclass *
-nv46_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x46),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+static int
+nv46_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv46_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+
+struct nouveau_oclass
+nv46_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x46),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv46_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv44_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv44_ram_oclass,
- .tile.regions = 15,
- .tile.init = nv46_fb_tile_init,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv44_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
index 3bea142..fe6a227 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
@@ -24,22 +24,42 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
-struct nouveau_oclass *
-nv47_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x47),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+struct nv47_fb_priv {
+ struct nouveau_fb base;
+};
+
+static int
+nv47_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv47_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+
+struct nouveau_oclass
+nv47_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x47),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv47_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv41_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv41_ram_oclass,
- .tile.regions = 15,
- .tile.init = nv30_fb_tile_init,
- .tile.comp = nv40_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv41_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
index 666cbd5..5eca99b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
@@ -24,22 +24,42 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
-struct nouveau_oclass *
-nv49_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x49),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+struct nv49_fb_priv {
+ struct nouveau_fb base;
+};
+
+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)
+{
+ struct nv49_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+
+struct nouveau_oclass
+nv49_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x49),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv49_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv41_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv49_ram_oclass,
- .tile.regions = 15,
- .tile.init = nv30_fb_tile_init,
- .tile.comp = nv40_fb_tile_comp,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv41_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
index 42e64f3..1190b78 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
@@ -24,21 +24,40 @@
*
*/
-#include "nv04.h"
+#include "priv.h"
-struct nouveau_oclass *
-nv4e_fb_oclass = &(struct nv04_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x4e),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_fb_ctor,
+struct nv4e_fb_priv {
+ struct nouveau_fb base;
+};
+
+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)
+{
+ struct nv4e_fb_priv *priv;
+ int ret;
+
+ 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.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 0;
+}
+
+struct nouveau_oclass
+nv4e_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x4e),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv4e_fb_ctor,
.dtor = _nouveau_fb_dtor,
.init = nv44_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv04_fb_memtype_valid,
- .base.ram = &nv4e_ram_oclass,
- .tile.regions = 12,
- .tile.init = nv46_fb_tile_init,
- .tile.fini = nv20_fb_tile_fini,
- .tile.prog = nv44_fb_tile_prog,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
index cbc7f00..da614ec 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
@@ -27,9 +27,14 @@
#include <core/engctx.h>
#include <core/object.h>
+#include "priv.h"
#include <subdev/bios.h>
-#include "nv50.h"
+struct nv50_fb_priv {
+ struct nouveau_fb base;
+ struct page *r100c08_page;
+ dma_addr_t r100c08;
+};
int
nv50_fb_memtype[0x80] = {
@@ -43,7 +48,7 @@ nv50_fb_memtype[0x80] = {
1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
};
-bool
+static bool
nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype)
{
return nv50_fb_memtype[(memtype & 0xff00) >> 8] != 0;
@@ -234,7 +239,7 @@ nv50_fb_intr(struct nouveau_subdev *subdev)
pr_cont("0x%08x\n", st1);
}
-int
+static int
nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -243,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;
@@ -259,11 +264,12 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_warn(priv, "failed 0x100c08 page alloc\n");
}
+ priv->base.memtype_valid = nv50_fb_memtype_valid;
nv_subdev(priv)->intr = nv50_fb_intr;
return 0;
}
-void
+static void
nv50_fb_dtor(struct nouveau_object *object)
{
struct nouveau_device *device = nv_device(object);
@@ -278,10 +284,10 @@ nv50_fb_dtor(struct nouveau_object *object)
nouveau_fb_destroy(&priv->base);
}
-int
+static int
nv50_fb_init(struct nouveau_object *object)
{
- struct nv50_fb_impl *impl = (void *)object->oclass;
+ struct nouveau_device *device = nv_device(object);
struct nv50_fb_priv *priv = (void *)object;
int ret;
@@ -297,20 +303,33 @@ nv50_fb_init(struct nouveau_object *object)
/* This is needed to get meaningful information from 100c90
* on traps. No idea what these values mean exactly. */
- nv_wr32(priv, 0x100c90, impl->trap);
+ switch (device->chipset) {
+ case 0x50:
+ nv_wr32(priv, 0x100c90, 0x000707ff);
+ break;
+ case 0xa3:
+ case 0xa5:
+ case 0xa8:
+ nv_wr32(priv, 0x100c90, 0x000d0fff);
+ break;
+ case 0xaf:
+ nv_wr32(priv, 0x100c90, 0x089d1fff);
+ break;
+ default:
+ nv_wr32(priv, 0x100c90, 0x001d07ff);
+ break;
+ }
+
return 0;
}
-struct nouveau_oclass *
-nv50_fb_oclass = &(struct nv50_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x50),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass
+nv50_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_fb_ctor,
.dtor = nv50_fb_dtor,
.init = nv50_fb_init,
.fini = _nouveau_fb_fini,
},
- .base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nv50_ram_oclass,
- .trap = 0x000707ff,
-}.base.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h
deleted file mode 100644
index c5e5a88..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __NVKM_FB_NV50_H__
-#define __NVKM_FB_NV50_H__
-
-#include "priv.h"
-
-struct nv50_fb_priv {
- struct nouveau_fb base;
- struct page *r100c08_page;
- dma_addr_t r100c08;
-};
-
-int nv50_fb_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv50_fb_dtor(struct nouveau_object *);
-int nv50_fb_init(struct nouveau_object *);
-
-struct nv50_fb_impl {
- struct nouveau_fb_impl base;
- u32 trap;
-};
-
-#define nv50_ram_create(p,e,o,d) \
- nv50_ram_create_((p), (e), (o), sizeof(**d), (void **)d)
-int nv50_ram_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-int nv50_ram_get(struct nouveau_fb *, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **);
-void nv50_ram_put(struct nouveau_fb *, struct nouveau_mem **);
-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/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c
deleted file mode 100644
index cf0e767..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 "nv50.h"
-
-struct nouveau_oclass *
-nv84_fb_oclass = &(struct nv50_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0x84),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_fb_ctor,
- .dtor = nv50_fb_dtor,
- .init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
- },
- .base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nv50_ram_oclass,
- .trap = 0x001d07ff,
-}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c
deleted file mode 100644
index dab6e1c..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 "nv50.h"
-
-struct nouveau_oclass *
-nva3_fb_oclass = &(struct nv50_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0xa3),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_fb_ctor,
- .dtor = nv50_fb_dtor,
- .init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
- },
- .base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nva3_ram_oclass,
- .trap = 0x000d0fff,
-}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c
deleted file mode 100644
index cba8e68..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 "nv50.h"
-
-struct nouveau_oclass *
-nvaa_fb_oclass = &(struct nv50_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0xaa),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_fb_ctor,
- .dtor = nv50_fb_dtor,
- .init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
- },
- .base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nvaa_ram_oclass,
- .trap = 0x001d07ff,
-}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c
deleted file mode 100644
index 5423faa..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 "nv50.h"
-
-struct nouveau_oclass *
-nvaf_fb_oclass = &(struct nv50_fb_impl) {
- .base.base.handle = NV_SUBDEV(FB, 0xaf),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_fb_ctor,
- .dtor = nv50_fb_dtor,
- .init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
- },
- .base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nvaa_ram_oclass,
- .trap = 0x089d1fff,
-}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index e5fc37c..f35d76f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -22,18 +22,24 @@
* Authors: Ben Skeggs
*/
-#include "nvc0.h"
+#include "priv.h"
+
+struct nvc0_fb_priv {
+ struct nouveau_fb base;
+ struct page *r100c10_page;
+ dma_addr_t r100c10;
+};
extern const u8 nvc0_pte_storage_type_map[256];
-bool
+static bool
nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
{
u8 memtype = (tile_flags & 0x0000ff00) >> 8;
return likely((nvc0_pte_storage_type_map[memtype] != 0xff));
}
-int
+static int
nvc0_fb_init(struct nouveau_object *object)
{
struct nvc0_fb_priv *priv = (void *)object;
@@ -48,7 +54,7 @@ nvc0_fb_init(struct nouveau_object *object)
return 0;
}
-void
+static void
nvc0_fb_dtor(struct nouveau_object *object)
{
struct nouveau_device *device = nv_device(object);
@@ -63,7 +69,7 @@ nvc0_fb_dtor(struct nouveau_object *object)
nouveau_fb_destroy(&priv->base);
}
-int
+static int
nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -72,11 +78,13 @@ 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->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (priv->r100c10_page) {
priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page,
@@ -89,15 +97,14 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nvc0_fb_oclass = &(struct nouveau_fb_impl) {
- .base.handle = NV_SUBDEV(FB, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+
+struct nouveau_oclass
+nvc0_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_fb_ctor,
.dtor = nvc0_fb_dtor,
.init = nvc0_fb_init,
.fini = _nouveau_fb_fini,
},
- .memtype = nvc0_fb_memtype_valid,
- .ram = &nvc0_ram_oclass,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h
deleted file mode 100644
index 9e1931e..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __NVKM_RAM_NVC0_H__
-#define __NVKM_RAM_NVC0_H__
-
-#include "priv.h"
-#include "nv50.h"
-
-struct nvc0_fb_priv {
- struct nouveau_fb base;
- struct page *r100c10_page;
- dma_addr_t r100c10;
-};
-
-int nvc0_fb_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nvc0_fb_dtor(struct nouveau_object *);
-int nvc0_fb_init(struct nouveau_object *);
-bool nvc0_fb_memtype_valid(struct nouveau_fb *, u32);
-
-
-#define nvc0_ram_create(p,e,o,d) \
- nvc0_ram_create_((p), (e), (o), sizeof(**d), (void **)d)
-int nvc0_ram_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-int nvc0_ram_get(struct nouveau_fb *, u64, u32, u32, u32,
- struct nouveau_mem **);
-void nvc0_ram_put(struct nouveau_fb *, struct nouveau_mem **);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c
deleted file mode 100644
index 595db50..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 "nvc0.h"
-
-struct nouveau_oclass *
-nve0_fb_oclass = &(struct nouveau_fb_impl) {
- .base.handle = NV_SUBDEV(FB, 0xe0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_fb_ctor,
- .dtor = nvc0_fb_dtor,
- .init = nvc0_fb_init,
- .fini = _nouveau_fb_fini,
- },
- .memtype = nvc0_fb_memtype_valid,
- .ram = &nve0_ram_oclass,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
index 4931252..db9d6dd 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
@@ -12,8 +12,6 @@
#define nouveau_ram_fini(p,s) \
nouveau_object_fini(&(p)->base, (s))
-#define nouveau_ram_create_(p,e,o,s,d) \
- nouveau_object_create_((p), (e), (o), 0, (s), (void **)d)
#define _nouveau_ram_dtor nouveau_object_destroy
#define _nouveau_ram_init nouveau_object_init
#define _nouveau_ram_fini nouveau_object_fini
@@ -28,16 +26,10 @@ 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 nva3_ram_oclass;
-extern struct nouveau_oclass nvaa_ram_oclass;
extern struct nouveau_oclass nvc0_ram_oclass;
-extern struct nouveau_oclass nve0_ram_oclass;
-int nouveau_sddr3_calc(struct nouveau_ram *ram);
-int nouveau_gddr5_calc(struct nouveau_ram *ram);
-
-#define nouveau_fb_create(p,e,c,d) \
- nouveau_fb_create_((p), (e), (c), sizeof(**d), (void **)d)
+#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)); \
@@ -52,21 +44,44 @@ int nouveau_gddr5_calc(struct nouveau_ram *ram);
})
int nouveau_fb_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
+ 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_fb_impl {
- struct nouveau_oclass base;
- struct nouveau_oclass *ram;
- bool (*memtype)(struct nouveau_fb *, u32);
-};
+struct nouveau_bios;
+int nouveau_fb_bios_memtype(struct nouveau_bios *);
bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
-bool nv50_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
-struct nouveau_bios;
-int nouveau_fb_bios_memtype(struct nouveau_bios *);
+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/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
deleted file mode 100644
index 0f57fcf..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef __NVKM_FBRAM_FUC_H__
-#define __NVKM_FBRAM_FUC_H__
-
-#include <subdev/pwr.h>
-
-struct ramfuc {
- struct nouveau_memx *memx;
- struct nouveau_fb *pfb;
- int sequence;
-};
-
-struct ramfuc_reg {
- int sequence;
- bool force;
- u32 addr[2];
- u32 data;
-};
-
-static inline struct ramfuc_reg
-ramfuc_reg2(u32 addr1, u32 addr2)
-{
- return (struct ramfuc_reg) {
- .sequence = 0,
- .addr = { addr1, addr2 },
- .data = 0xdeadbeef,
- };
-}
-
-static inline struct ramfuc_reg
-ramfuc_reg(u32 addr)
-{
- return ramfuc_reg2(addr, addr);
-}
-
-static inline int
-ramfuc_init(struct ramfuc *ram, struct nouveau_fb *pfb)
-{
- struct nouveau_pwr *ppwr = nouveau_pwr(pfb);
- int ret;
-
- ret = nouveau_memx_init(ppwr, &ram->memx);
- if (ret)
- return ret;
-
- ram->sequence++;
- ram->pfb = pfb;
- return 0;
-}
-
-static inline int
-ramfuc_exec(struct ramfuc *ram, bool exec)
-{
- int ret = 0;
- if (ram->pfb) {
- ret = nouveau_memx_fini(&ram->memx, exec);
- ram->pfb = NULL;
- }
- return ret;
-}
-
-static inline u32
-ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg)
-{
- if (reg->sequence != ram->sequence)
- reg->data = nv_rd32(ram->pfb, reg->addr[0]);
- return reg->data;
-}
-
-static inline void
-ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data)
-{
- reg->sequence = ram->sequence;
- reg->data = data;
- if (reg->addr[0] != reg->addr[1])
- nouveau_memx_wr32(ram->memx, reg->addr[1], reg->data);
- nouveau_memx_wr32(ram->memx, reg->addr[0], reg->data);
-}
-
-static inline void
-ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg)
-{
- reg->force = true;
-}
-
-static inline u32
-ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data)
-{
- u32 temp = ramfuc_rd32(ram, reg);
- if (temp != ((temp & ~mask) | data) || reg->force) {
- ramfuc_wr32(ram, reg, (temp & ~mask) | data);
- reg->force = false;
- }
- return temp;
-}
-
-static inline void
-ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec)
-{
- nouveau_memx_wait(ram->memx, addr, mask, data, nsec);
-}
-
-static inline void
-ramfuc_nsec(struct ramfuc *ram, u32 nsec)
-{
- nouveau_memx_nsec(ram->memx, nsec);
-}
-
-#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
-#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
-#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
-#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
-#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
-#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
-#define ram_mask(s,r,m,d) ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d))
-#define ram_wait(s,r,m,d,n) ramfuc_wait(&(s)->base, (r), (m), (d), (n))
-#define ram_nsec(s,n) ramfuc_nsec(&(s)->base, (n))
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
index 7648beb..ee49ac4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
@@ -22,154 +22,7 @@
* Authors: Ben Skeggs
*/
-#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/pll.h>
-#include <subdev/bios/init.h>
-#include <subdev/clock.h>
-#include <subdev/clock/pll.h>
-#include <subdev/timer.h>
-
-#include <engine/fifo.h>
-
-#include "nv40.h"
-
-int
-nv40_ram_calc(struct nouveau_fb *pfb, u32 freq)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nv40_ram *ram = (void *)pfb->ram;
- struct nvbios_pll pll;
- int N1, M1, N2, M2;
- int log2P, ret;
-
- ret = nvbios_pll_parse(bios, 0x04, &pll);
- if (ret) {
- nv_error(pfb, "mclk pll data not found\n");
- return ret;
- }
-
- ret = nv04_pll_calc(nv_subdev(pfb), &pll, freq,
- &N1, &M1, &N2, &M2, &log2P);
- if (ret < 0)
- return ret;
-
- ram->ctrl = 0x80000000 | (log2P << 16);
- ram->ctrl |= min(pll.bias_p + log2P, (int)pll.max_p) << 20;
- if (N2 == M2) {
- ram->ctrl |= 0x00000100;
- ram->coef = (N1 << 8) | M1;
- } else {
- ram->ctrl |= 0x40000000;
- ram->coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1;
- }
-
- return 0;
-}
-
-int
-nv40_ram_prog(struct nouveau_fb *pfb)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nv40_ram *ram = (void *)pfb->ram;
- struct bit_entry M;
- u32 crtc_mask = 0;
- u8 sr1[2];
- int i;
-
- /* determine which CRTCs are active, fetch VGA_SR1 for each */
- for (i = 0; i < 2; i++) {
- u32 vbl = nv_rd32(pfb, 0x600808 + (i * 0x2000));
- u32 cnt = 0;
- do {
- if (vbl != nv_rd32(pfb, 0x600808 + (i * 0x2000))) {
- nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
- sr1[i] = nv_rd08(pfb, 0x0c03c5 + (i * 0x2000));
- if (!(sr1[i] & 0x20))
- crtc_mask |= (1 << i);
- break;
- }
- udelay(1);
- } while (cnt++ < 32);
- }
-
- /* wait for vblank start on active crtcs, disable memory access */
- for (i = 0; i < 2; i++) {
- if (!(crtc_mask & (1 << i)))
- continue;
- nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000);
- nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
- nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
- nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
- }
-
- /* prepare ram for reclocking */
- nv_wr32(pfb, 0x1002d4, 0x00000001); /* precharge */
- nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */
- nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */
- nv_mask(pfb, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
- nv_wr32(pfb, 0x1002dc, 0x00000001); /* enable self-refresh */
-
- /* change the PLL of each memory partition */
- nv_mask(pfb, 0x00c040, 0x0000c000, 0x00000000);
- switch (nv_device(pfb)->chipset) {
- case 0x40:
- case 0x45:
- case 0x41:
- case 0x42:
- case 0x47:
- nv_mask(pfb, 0x004044, 0xc0771100, ram->ctrl);
- nv_mask(pfb, 0x00402c, 0xc0771100, ram->ctrl);
- nv_wr32(pfb, 0x004048, ram->coef);
- nv_wr32(pfb, 0x004030, ram->coef);
- case 0x43:
- case 0x49:
- case 0x4b:
- nv_mask(pfb, 0x004038, 0xc0771100, ram->ctrl);
- nv_wr32(pfb, 0x00403c, ram->coef);
- default:
- nv_mask(pfb, 0x004020, 0xc0771100, ram->ctrl);
- nv_wr32(pfb, 0x004024, ram->coef);
- break;
- }
- udelay(100);
- nv_mask(pfb, 0x00c040, 0x0000c000, 0x0000c000);
-
- /* re-enable normal operation of memory controller */
- nv_wr32(pfb, 0x1002dc, 0x00000000);
- nv_mask(pfb, 0x100210, 0x80000000, 0x80000000);
- udelay(100);
-
- /* execute memory reset script from vbios */
- if (!bit_entry(bios, 'M', &M)) {
- struct nvbios_init init = {
- .subdev = nv_subdev(pfb),
- .bios = bios,
- .offset = nv_ro16(bios, M.offset + 0x00),
- .execute = 1,
- };
-
- nvbios_exec(&init);
- }
-
- /* make sure we're in vblank (hopefully the same one as before), and
- * then re-enable crtc memory access
- */
- for (i = 0; i < 2; i++) {
- if (!(crtc_mask & (1 << i)))
- continue;
- nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
- nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
- nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i]);
- }
-
- return 0;
-}
-
-void
-nv40_ram_tidy(struct nouveau_fb *pfb)
-{
-}
+#include "priv.h"
static int
nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -177,7 +30,7 @@ nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_object **pobject)
{
struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nv40_ram *ram;
+ struct nouveau_ram *ram;
u32 pbus1218 = nv_rd32(pfb, 0x001218);
int ret;
@@ -187,18 +40,15 @@ nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
switch (pbus1218 & 0x00000300) {
- case 0x00000000: ram->base.type = NV_MEM_TYPE_SDRAM; break;
- case 0x00000100: ram->base.type = NV_MEM_TYPE_DDR1; break;
- case 0x00000200: ram->base.type = NV_MEM_TYPE_GDDR3; break;
- case 0x00000300: ram->base.type = NV_MEM_TYPE_DDR2; break;
+ 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->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
- ram->base.tags = nv_rd32(pfb, 0x100320);
- ram->base.calc = nv40_ram_calc;
- ram->base.prog = nv40_ram_prog;
- ram->base.tidy = nv40_ram_tidy;
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
index d64498a..1dab7e1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
@@ -22,7 +22,7 @@
* Authors: Ben Skeggs
*/
-#include "nv40.h"
+#include "priv.h"
static int
nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -30,7 +30,7 @@ nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_object **pobject)
{
struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nv40_ram *ram;
+ struct nouveau_ram *ram;
u32 pfb474 = nv_rd32(pfb, 0x100474);
int ret;
@@ -40,18 +40,15 @@ nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
if (pfb474 & 0x00000004)
- ram->base.type = NV_MEM_TYPE_GDDR3;
+ ram->type = NV_MEM_TYPE_GDDR3;
if (pfb474 & 0x00000002)
- ram->base.type = NV_MEM_TYPE_DDR2;
+ ram->type = NV_MEM_TYPE_DDR2;
if (pfb474 & 0x00000001)
- ram->base.type = NV_MEM_TYPE_DDR1;
+ ram->type = NV_MEM_TYPE_DDR1;
- ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
- ram->base.tags = nv_rd32(pfb, 0x100320);
- ram->base.calc = nv40_ram_calc;
- ram->base.prog = nv40_ram_prog;
- ram->base.tidy = nv40_ram_tidy;
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
index 089acac..25fff84 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
@@ -22,7 +22,7 @@
* Authors: Ben Skeggs
*/
-#include "nv40.h"
+#include "priv.h"
static int
nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -30,7 +30,7 @@ nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_object **pobject)
{
struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nv40_ram *ram;
+ struct nouveau_ram *ram;
u32 pfb474 = nv_rd32(pfb, 0x100474);
int ret;
@@ -40,16 +40,13 @@ nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
if (pfb474 & 0x00000004)
- ram->base.type = NV_MEM_TYPE_GDDR3;
+ ram->type = NV_MEM_TYPE_GDDR3;
if (pfb474 & 0x00000002)
- ram->base.type = NV_MEM_TYPE_DDR2;
+ ram->type = NV_MEM_TYPE_DDR2;
if (pfb474 & 0x00000001)
- ram->base.type = NV_MEM_TYPE_DDR1;
+ ram->type = NV_MEM_TYPE_DDR1;
- ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- ram->base.calc = nv40_ram_calc;
- ram->base.prog = nv40_ram_prog;
- ram->base.tidy = nv40_ram_tidy;
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
index baa013a..ab7ef0a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
@@ -22,7 +22,7 @@
* Authors: Ben Skeggs
*/
-#include "nv40.h"
+#include "priv.h"
static int
nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -30,7 +30,7 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_object **pobject)
{
struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nv40_ram *ram;
+ struct nouveau_ram *ram;
u32 pfb914 = nv_rd32(pfb, 0x100914);
int ret;
@@ -40,18 +40,15 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
switch (pfb914 & 0x00000003) {
- case 0x00000000: ram->base.type = NV_MEM_TYPE_DDR1; break;
- case 0x00000001: ram->base.type = NV_MEM_TYPE_DDR2; break;
- case 0x00000002: ram->base.type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000000: ram->type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000001: ram->type = NV_MEM_TYPE_DDR2; break;
+ case 0x00000002: ram->type = NV_MEM_TYPE_GDDR3; break;
case 0x00000003: break;
}
- ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
- ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
- ram->base.tags = nv_rd32(pfb, 0x100320);
- ram->base.calc = nv40_ram_calc;
- ram->base.prog = nv40_ram_prog;
- ram->base.tidy = nv40_ram_tidy;
+ ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+ ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
index 76762a1..903baff 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
@@ -23,215 +23,8 @@
*/
#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/pll.h>
-#include <subdev/bios/perf.h>
-#include <subdev/bios/timing.h>
-#include <subdev/clock/pll.h>
-#include <subdev/fb.h>
-
-#include <core/option.h>
#include <core/mm.h>
-
-#include "ramseq.h"
-
-#include "nv50.h"
-
-struct nv50_ramseq {
- struct hwsq base;
- struct hwsq_reg r_0x002504;
- struct hwsq_reg r_0x004008;
- struct hwsq_reg r_0x00400c;
- struct hwsq_reg r_0x00c040;
- struct hwsq_reg r_0x100210;
- struct hwsq_reg r_0x1002d0;
- struct hwsq_reg r_0x1002d4;
- struct hwsq_reg r_0x1002dc;
- struct hwsq_reg r_0x100da0[8];
- struct hwsq_reg r_0x100e20;
- struct hwsq_reg r_0x100e24;
- struct hwsq_reg r_0x611200;
- struct hwsq_reg r_timing[9];
- struct hwsq_reg r_mr[4];
-};
-
-struct nv50_ram {
- struct nouveau_ram base;
- struct nv50_ramseq hwsq;
-};
-
-#define QFX5800NVA0 1
-
-static int
-nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nv50_ram *ram = (void *)pfb->ram;
- struct nv50_ramseq *hwsq = &ram->hwsq;
- struct nvbios_perfE perfE;
- struct nvbios_pll mpll;
- struct bit_entry M;
- struct {
- u32 data;
- u8 size;
- } ramcfg, timing;
- u8 ver, hdr, cnt, strap;
- u32 data;
- int N1, M1, N2, M2, P;
- int ret, i;
-
- /* lookup closest matching performance table entry for frequency */
- i = 0;
- do {
- ramcfg.data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
- &ramcfg.size, &perfE);
- if (!ramcfg.data || (ver < 0x25 || ver >= 0x40) ||
- (ramcfg.size < 2)) {
- nv_error(pfb, "invalid/missing perftab entry\n");
- return -EINVAL;
- }
- } while (perfE.memory < freq);
-
- /* locate specific data set for the attached memory */
- if (bit_entry(bios, 'M', &M) || M.version != 1 || M.length < 5) {
- nv_error(pfb, "invalid/missing memory table\n");
- return -EINVAL;
- }
-
- strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
- data = nv_ro16(bios, M.offset + 3);
- if (data)
- strap = nv_ro08(bios, data + strap);
-
- if (strap >= cnt) {
- nv_error(pfb, "invalid ramcfg strap\n");
- return -EINVAL;
- }
-
- ramcfg.data += hdr + (strap * ramcfg.size);
-
- /* lookup memory timings, if bios says they're present */
- strap = nv_ro08(bios, ramcfg.data + 0x01);
- if (strap != 0xff) {
- timing.data = nvbios_timing_entry(bios, strap, &ver, &hdr);
- if (!timing.data || ver != 0x10 || hdr < 0x12) {
- nv_error(pfb, "invalid/missing timing entry "
- "%02x %04x %02x %02x\n",
- strap, timing.data, ver, hdr);
- return -EINVAL;
- }
- } else {
- timing.data = 0;
- }
-
- ret = ram_init(hwsq, nv_subdev(pfb));
- if (ret)
- return ret;
-
- ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
- ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
- ram_wr32(hwsq, 0x611200, 0x00003300);
- ram_wr32(hwsq, 0x002504, 0x00000001); /* block fifo */
- ram_nsec(hwsq, 8000);
- ram_setf(hwsq, 0x10, 0x00); /* disable fb */
- ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
-
- ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */
- ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
- ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
- ram_wr32(hwsq, 0x100210, 0x00000000); /* disable auto-refresh */
- ram_wr32(hwsq, 0x1002dc, 0x00000001); /* enable self-refresh */
-
- ret = nvbios_pll_parse(bios, 0x004008, &mpll);
- mpll.vco2.max_freq = 0;
- if (ret == 0) {
- ret = nv04_pll_calc(nv_subdev(pfb), &mpll, freq,
- &N1, &M1, &N2, &M2, &P);
- if (ret == 0)
- ret = -EINVAL;
- }
-
- if (ret < 0)
- return ret;
-
- ram_mask(hwsq, 0x00c040, 0xc000c000, 0x0000c000);
- ram_mask(hwsq, 0x004008, 0x00000200, 0x00000200);
- ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1);
- ram_mask(hwsq, 0x004008, 0x81ff0000, 0x80000000 | (mpll.bias_p << 19) |
- (P << 22) | (P << 16));
-#if QFX5800NVA0
- for (i = 0; i < 8; i++)
- ram_mask(hwsq, 0x100da0[i], 0x00000000, 0x00000000); /*XXX*/
-#endif
- ram_nsec(hwsq, 96000); /*XXX*/
- ram_mask(hwsq, 0x004008, 0x00002200, 0x00002000);
-
- ram_wr32(hwsq, 0x1002dc, 0x00000000); /* disable self-refresh */
- ram_wr32(hwsq, 0x100210, 0x80000000); /* enable auto-refresh */
-
- ram_nsec(hwsq, 12000);
-
- switch (ram->base.type) {
- case NV_MEM_TYPE_DDR2:
- ram_nuke(hwsq, mr[0]); /* force update */
- ram_mask(hwsq, mr[0], 0x000, 0x000);
- break;
- case NV_MEM_TYPE_GDDR3:
- ram_mask(hwsq, mr[2], 0x000, 0x000);
- ram_nuke(hwsq, mr[0]); /* force update */
- ram_mask(hwsq, mr[0], 0x000, 0x000);
- break;
- default:
- break;
- }
-
- ram_mask(hwsq, timing[3], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[1], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[6], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[7], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[8], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[2], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[4], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[5], 0x00000000, 0x00000000); /*XXX*/
-
- ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
-
-#if QFX5800NVA0
- ram_nuke(hwsq, 0x100e24);
- ram_mask(hwsq, 0x100e24, 0x00000000, 0x00000000);
- ram_nuke(hwsq, 0x100e20);
- ram_mask(hwsq, 0x100e20, 0x00000000, 0x00000000);
-#endif
-
- ram_mask(hwsq, mr[0], 0x100, 0x100);
- ram_mask(hwsq, mr[0], 0x100, 0x000);
-
- ram_setf(hwsq, 0x10, 0x01); /* enable fb */
- ram_wait(hwsq, 0x00, 0x00); /* wait for fb enabled */
- ram_wr32(hwsq, 0x611200, 0x00003330);
- ram_wr32(hwsq, 0x002504, 0x00000000); /* un-block fifo */
- return 0;
-}
-
-static int
-nv50_ram_prog(struct nouveau_fb *pfb)
-{
- struct nouveau_device *device = nv_device(pfb);
- struct nv50_ram *ram = (void *)pfb->ram;
- struct nv50_ramseq *hwsq = &ram->hwsq;
-
- ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
- return 0;
-}
-
-static void
-nv50_ram_tidy(struct nouveau_fb *pfb)
-{
- struct nv50_ram *ram = (void *)pfb->ram;
- struct nv50_ramseq *hwsq = &ram->hwsq;
- ram_exec(hwsq, false);
-}
+#include "priv.h"
void
__nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem)
@@ -264,7 +57,7 @@ nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
kfree(mem);
}
-int
+static int
nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
u32 memtype, struct nouveau_mem **pmem)
{
@@ -367,114 +160,77 @@ nv50_fb_vram_rblock(struct nouveau_fb *pfb, struct nouveau_ram *ram)
return rblock_size;
}
-int
-nv50_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+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)
{
- const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
- const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
- struct nouveau_bios *bios = nouveau_bios(parent);
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, length, pobject);
- ram = *pobject;
+ 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);
+ 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;
- 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;
+ ram->type = NV_MEM_TYPE_STOLEN;
+ ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
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, (ram->size >> 12) -
- (rsvd_head + rsvd_tail),
- 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);
- ram->get = nv50_ram_get;
- ram->put = nv50_ram_put;
- return 0;
-}
-
-static int
-nv50_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 datasize,
- struct nouveau_object **pobject)
-{
- struct nv50_ram *ram;
- int ret, i;
+ 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 = nv50_ram_create(parent, engine, oclass, &ram);
- *pobject = nv_object(ram);
- if (ret)
- return ret;
+ ret = nouveau_mm_init(&pfb->vram, rsvd_head, size,
+ nv50_fb_vram_rblock(pfb, ram) >> 12);
+ if (ret)
+ return ret;
- switch (ram->base.type) {
- case NV_MEM_TYPE_DDR2:
- case NV_MEM_TYPE_GDDR3:
- ram->base.calc = nv50_ram_calc;
- ram->base.prog = nv50_ram_prog;
- ram->base.tidy = nv50_ram_tidy;
+ ram->ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1;
+ ram->tags = nv_rd32(pfb, 0x100320);
break;
- default:
- nv_warn(ram, "reclocking of this ram type unsupported\n");
- return 0;
- }
-
- ram->hwsq.r_0x002504 = hwsq_reg(0x002504);
- ram->hwsq.r_0x00c040 = hwsq_reg(0x00c040);
- ram->hwsq.r_0x004008 = hwsq_reg(0x004008);
- ram->hwsq.r_0x00400c = hwsq_reg(0x00400c);
- ram->hwsq.r_0x100210 = hwsq_reg(0x100210);
- ram->hwsq.r_0x1002d0 = hwsq_reg(0x1002d0);
- ram->hwsq.r_0x1002d4 = hwsq_reg(0x1002d4);
- ram->hwsq.r_0x1002dc = hwsq_reg(0x1002dc);
- for (i = 0; i < 8; i++)
- ram->hwsq.r_0x100da0[i] = hwsq_reg(0x100da0 + (i * 0x04));
- ram->hwsq.r_0x100e20 = hwsq_reg(0x100e20);
- ram->hwsq.r_0x100e24 = hwsq_reg(0x100e24);
- ram->hwsq.r_0x611200 = hwsq_reg(0x611200);
-
- for (i = 0; i < 9; i++)
- ram->hwsq.r_timing[i] = hwsq_reg(0x100220 + (i * 0x04));
-
- if (ram->base.ranks > 1) {
- ram->hwsq.r_mr[0] = hwsq_reg2(0x1002c0, 0x1002c8);
- ram->hwsq.r_mr[1] = hwsq_reg2(0x1002c4, 0x1002cc);
- ram->hwsq.r_mr[2] = hwsq_reg2(0x1002e0, 0x1002e8);
- ram->hwsq.r_mr[3] = hwsq_reg2(0x1002e4, 0x1002ec);
- } else {
- ram->hwsq.r_mr[0] = hwsq_reg(0x1002c0);
- ram->hwsq.r_mr[1] = hwsq_reg(0x1002c4);
- ram->hwsq.r_mr[2] = hwsq_reg(0x1002e0);
- ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4);
}
+ 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_ctor,
+ .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/ramnva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
deleted file mode 100644
index f6292cd..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * 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/bios/bit.h>
-#include <subdev/bios/pll.h>
-#include <subdev/bios/rammap.h>
-#include <subdev/bios/timing.h>
-
-#include <subdev/clock/nva3.h>
-#include <subdev/clock/pll.h>
-
-#include <core/option.h>
-
-#include "ramfuc.h"
-
-#include "nv50.h"
-
-struct nva3_ramfuc {
- struct ramfuc base;
- struct ramfuc_reg r_0x004000;
- struct ramfuc_reg r_0x004004;
- struct ramfuc_reg r_0x004018;
- struct ramfuc_reg r_0x004128;
- struct ramfuc_reg r_0x004168;
- struct ramfuc_reg r_0x100200;
- struct ramfuc_reg r_0x100210;
- struct ramfuc_reg r_0x100220[9];
- struct ramfuc_reg r_0x1002d0;
- struct ramfuc_reg r_0x1002d4;
- struct ramfuc_reg r_0x1002dc;
- struct ramfuc_reg r_0x10053c;
- struct ramfuc_reg r_0x1005a0;
- struct ramfuc_reg r_0x1005a4;
- struct ramfuc_reg r_0x100714;
- struct ramfuc_reg r_0x100718;
- struct ramfuc_reg r_0x10071c;
- struct ramfuc_reg r_0x100760;
- struct ramfuc_reg r_0x1007a0;
- struct ramfuc_reg r_0x1007e0;
- struct ramfuc_reg r_0x10f804;
- struct ramfuc_reg r_0x1110e0;
- struct ramfuc_reg r_0x111100;
- struct ramfuc_reg r_0x111104;
- struct ramfuc_reg r_0x611200;
- struct ramfuc_reg r_mr[4];
-};
-
-struct nva3_ram {
- struct nouveau_ram base;
- struct nva3_ramfuc fuc;
-};
-
-static int
-nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nva3_ramfuc *fuc = &ram->fuc;
- struct nva3_clock_info mclk;
- struct bit_entry M;
- u8 ver, cnt, strap;
- u32 data;
- struct {
- u32 data;
- u8 size;
- } rammap, ramcfg, timing;
- u32 r004018, r100760, ctrl;
- u32 unk714, unk718, unk71c;
- int ret;
-
- /* lookup memory config data relevant to the target frequency */
- rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size,
- &cnt, &ramcfg.size);
- if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
- nv_error(pfb, "invalid/missing rammap entry\n");
- return -EINVAL;
- }
-
- /* locate specific data set for the attached memory */
- if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) {
- nv_error(pfb, "invalid/missing memory table\n");
- return -EINVAL;
- }
-
- strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
- data = nv_ro16(bios, M.offset + 1);
- if (data)
- strap = nv_ro08(bios, data + strap);
-
- if (strap >= cnt) {
- nv_error(pfb, "invalid ramcfg strap\n");
- return -EINVAL;
- }
-
- ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
- if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
- nv_error(pfb, "invalid/missing ramcfg entry\n");
- return -EINVAL;
- }
-
- /* lookup memory timings, if bios says they're present */
- strap = nv_ro08(bios, ramcfg.data + 0x01);
- if (strap != 0xff) {
- timing.data = nvbios_timing_entry(bios, strap, &ver,
- &timing.size);
- if (!timing.data || ver != 0x10 || timing.size < 0x19) {
- nv_error(pfb, "invalid/missing timing entry\n");
- return -EINVAL;
- }
- } else {
- timing.data = 0;
- }
-
- ret = nva3_clock_info(nouveau_clock(pfb), 0x12, 0x4000, freq, &mclk);
- if (ret < 0) {
- nv_error(pfb, "failed mclk calculation\n");
- return ret;
- }
-
- ret = ram_init(fuc, pfb);
- if (ret)
- return ret;
-
- /* XXX: where the fuck does 750MHz come from? */
- if (freq <= 750000) {
- r004018 = 0x10000000;
- r100760 = 0x22222222;
- } else {
- r004018 = 0x00000000;
- r100760 = 0x00000000;
- }
-
- ctrl = ram_rd32(fuc, 0x004000);
- if (ctrl & 0x00000008) {
- if (mclk.pll) {
- ram_mask(fuc, 0x004128, 0x00000101, 0x00000101);
- ram_wr32(fuc, 0x004004, mclk.pll);
- ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001));
- ram_wr32(fuc, 0x004000, (ctrl &= 0xffffffef));
- ram_wait(fuc, 0x004000, 0x00020000, 0x00020000, 64000);
- ram_wr32(fuc, 0x004000, (ctrl |= 0x00000010));
- ram_wr32(fuc, 0x004018, 0x00005000 | r004018);
- ram_wr32(fuc, 0x004000, (ctrl |= 0x00000004));
- }
- } else {
- u32 ssel = 0x00000101;
- if (mclk.clk)
- ssel |= mclk.clk;
- else
- ssel |= 0x00080000; /* 324MHz, shouldn't matter... */
- ram_mask(fuc, 0x004168, 0x003f3141, ctrl);
- }
-
- if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) {
- ram_mask(fuc, 0x111104, 0x00000600, 0x00000000);
- } else {
- ram_mask(fuc, 0x111100, 0x40000000, 0x40000000);
- ram_mask(fuc, 0x111104, 0x00000180, 0x00000000);
- }
-
- if (!(nv_ro08(bios, rammap.data + 0x04) & 0x02))
- ram_mask(fuc, 0x100200, 0x00000800, 0x00000000);
- ram_wr32(fuc, 0x611200, 0x00003300);
- if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x10))
- ram_wr32(fuc, 0x111100, 0x4c020000); /*XXX*/
-
- ram_wr32(fuc, 0x1002d4, 0x00000001);
- ram_wr32(fuc, 0x1002d0, 0x00000001);
- ram_wr32(fuc, 0x1002d0, 0x00000001);
- ram_wr32(fuc, 0x100210, 0x00000000);
- ram_wr32(fuc, 0x1002dc, 0x00000001);
- ram_nsec(fuc, 2000);
-
- ctrl = ram_rd32(fuc, 0x004000);
- if (!(ctrl & 0x00000008) && mclk.pll) {
- ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008));
- ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000);
- ram_wr32(fuc, 0x004018, 0x00001000);
- ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000001));
- ram_wr32(fuc, 0x004004, mclk.pll);
- ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001));
- udelay(64);
- ram_wr32(fuc, 0x004018, 0x00005000 | r004018);
- udelay(20);
- } else
- if (!mclk.pll) {
- ram_mask(fuc, 0x004168, 0x003f3040, mclk.clk);
- ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008));
- ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000);
- ram_wr32(fuc, 0x004018, 0x0000d000 | r004018);
- }
-
- if ( (nv_ro08(bios, rammap.data + 0x04) & 0x08)) {
- u32 unk5a0 = (nv_ro16(bios, ramcfg.data + 0x05) << 8) |
- nv_ro08(bios, ramcfg.data + 0x05);
- u32 unk5a4 = (nv_ro16(bios, ramcfg.data + 0x07));
- u32 unk804 = (nv_ro08(bios, ramcfg.data + 0x09) & 0xf0) << 16 |
- (nv_ro08(bios, ramcfg.data + 0x03) & 0x0f) << 16 |
- (nv_ro08(bios, ramcfg.data + 0x09) & 0x0f) |
- 0x80000000;
- ram_wr32(fuc, 0x1005a0, unk5a0);
- ram_wr32(fuc, 0x1005a4, unk5a4);
- ram_wr32(fuc, 0x10f804, unk804);
- ram_mask(fuc, 0x10053c, 0x00001000, 0x00000000);
- } else {
- ram_mask(fuc, 0x10053c, 0x00001000, 0x00001000);
- ram_mask(fuc, 0x10f804, 0x80000000, 0x00000000);
- ram_mask(fuc, 0x100760, 0x22222222, r100760);
- ram_mask(fuc, 0x1007a0, 0x22222222, r100760);
- ram_mask(fuc, 0x1007e0, 0x22222222, r100760);
- }
-
- if (mclk.pll) {
- ram_mask(fuc, 0x1110e0, 0x00088000, 0x00011000);
- ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000008));
- }
-
- /*XXX: LEAVE */
- ram_wr32(fuc, 0x1002dc, 0x00000000);
- ram_wr32(fuc, 0x1002d4, 0x00000001);
- ram_wr32(fuc, 0x100210, 0x80000000);
- ram_nsec(fuc, 1000);
- ram_nsec(fuc, 1000);
-
- ram_mask(fuc, mr[2], 0x00000000, 0x00000000);
- ram_nsec(fuc, 1000);
- ram_nuke(fuc, mr[0]);
- ram_mask(fuc, mr[0], 0x00000000, 0x00000000);
- ram_nsec(fuc, 1000);
-
- ram_mask(fuc, 0x100220[3], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[1], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[6], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[7], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[2], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[4], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[5], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[0], 0x00000000, 0x00000000);
- ram_mask(fuc, 0x100220[8], 0x00000000, 0x00000000);
-
- data = (nv_ro08(bios, ramcfg.data + 0x02) & 0x08) ? 0x00000000 : 0x00001000;
- ram_mask(fuc, 0x100200, 0x00001000, data);
-
- unk714 = ram_rd32(fuc, 0x100714) & ~0xf0000010;
- unk718 = ram_rd32(fuc, 0x100718) & ~0x00000100;
- unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100;
- if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x20))
- unk714 |= 0xf0000000;
- if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x04))
- unk714 |= 0x00000010;
- ram_wr32(fuc, 0x100714, unk714);
-
- if (nv_ro08(bios, ramcfg.data + 0x02) & 0x01)
- unk71c |= 0x00000100;
- ram_wr32(fuc, 0x10071c, unk71c);
-
- if (nv_ro08(bios, ramcfg.data + 0x02) & 0x02)
- unk718 |= 0x00000100;
- ram_wr32(fuc, 0x100718, unk718);
-
- if (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)
- ram_wr32(fuc, 0x111100, 0x48000000); /*XXX*/
-
- ram_mask(fuc, mr[0], 0x100, 0x100);
- ram_nsec(fuc, 1000);
- ram_mask(fuc, mr[0], 0x100, 0x000);
- ram_nsec(fuc, 1000);
-
- ram_nsec(fuc, 2000);
- ram_nsec(fuc, 12000);
-
- ram_wr32(fuc, 0x611200, 0x00003330);
- if ( (nv_ro08(bios, rammap.data + 0x04) & 0x02))
- ram_mask(fuc, 0x100200, 0x00000800, 0x00000800);
- if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) {
- ram_mask(fuc, 0x111104, 0x00000180, 0x00000180);
- ram_mask(fuc, 0x111100, 0x40000000, 0x00000000);
- } else {
- ram_mask(fuc, 0x111104, 0x00000600, 0x00000600);
- }
-
- if (mclk.pll) {
- ram_mask(fuc, 0x004168, 0x00000001, 0x00000000);
- ram_mask(fuc, 0x004168, 0x00000100, 0x00000000);
- } else {
- ram_mask(fuc, 0x004000, 0x00000001, 0x00000000);
- ram_mask(fuc, 0x004128, 0x00000001, 0x00000000);
- ram_mask(fuc, 0x004128, 0x00000100, 0x00000000);
- }
-
- return 0;
-}
-
-static int
-nva3_ram_prog(struct nouveau_fb *pfb)
-{
- struct nouveau_device *device = nv_device(pfb);
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nva3_ramfuc *fuc = &ram->fuc;
- ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
- return 0;
-}
-
-static void
-nva3_ram_tidy(struct nouveau_fb *pfb)
-{
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nva3_ramfuc *fuc = &ram->fuc;
- ram_exec(fuc, false);
-}
-
-static int
-nva3_ram_init(struct nouveau_object *object)
-{
- struct nouveau_fb *pfb = (void *)object->parent;
- struct nva3_ram *ram = (void *)object;
- int ret, i;
-
- ret = nouveau_ram_init(&ram->base);
- if (ret)
- return ret;
-
- /* prepare for ddr link training, and load training patterns */
- switch (ram->base.type) {
- case NV_MEM_TYPE_DDR3: {
- static const u32 pattern[16] = {
- 0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee,
- 0x00000000, 0x11111111, 0x44444444, 0xdddddddd,
- 0x33333333, 0x55555555, 0x77777777, 0x66666666,
- 0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb,
- };
-
- nv_wr32(pfb, 0x100538, 0x10001ff6); /*XXX*/
- nv_wr32(pfb, 0x1005a8, 0x0000ffff);
- nv_mask(pfb, 0x10f800, 0x00000001, 0x00000001);
- for (i = 0; i < 0x30; i++) {
- nv_wr32(pfb, 0x10f8c0, (i << 8) | i);
- nv_wr32(pfb, 0x10f8e0, (i << 8) | i);
- nv_wr32(pfb, 0x10f900, pattern[i % 16]);
- nv_wr32(pfb, 0x10f920, pattern[i % 16]);
- }
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int
-nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 datasize,
- struct nouveau_object **pobject)
-{
- struct nva3_ram *ram;
- int ret, i;
-
- ret = nv50_ram_create(parent, engine, oclass, &ram);
- *pobject = nv_object(ram);
- if (ret)
- return ret;
-
- switch (ram->base.type) {
- case NV_MEM_TYPE_DDR3:
- ram->base.calc = nva3_ram_calc;
- ram->base.prog = nva3_ram_prog;
- ram->base.tidy = nva3_ram_tidy;
- break;
- default:
- nv_warn(ram, "reclocking of this ram type unsupported\n");
- return 0;
- }
-
- ram->fuc.r_0x004000 = ramfuc_reg(0x004000);
- ram->fuc.r_0x004004 = ramfuc_reg(0x004004);
- ram->fuc.r_0x004018 = ramfuc_reg(0x004018);
- ram->fuc.r_0x004128 = ramfuc_reg(0x004128);
- ram->fuc.r_0x004168 = ramfuc_reg(0x004168);
- ram->fuc.r_0x100200 = ramfuc_reg(0x100200);
- ram->fuc.r_0x100210 = ramfuc_reg(0x100210);
- for (i = 0; i < 9; i++)
- ram->fuc.r_0x100220[i] = ramfuc_reg(0x100220 + (i * 4));
- ram->fuc.r_0x1002d0 = ramfuc_reg(0x1002d0);
- ram->fuc.r_0x1002d4 = ramfuc_reg(0x1002d4);
- ram->fuc.r_0x1002dc = ramfuc_reg(0x1002dc);
- ram->fuc.r_0x10053c = ramfuc_reg(0x10053c);
- ram->fuc.r_0x1005a0 = ramfuc_reg(0x1005a0);
- ram->fuc.r_0x1005a4 = ramfuc_reg(0x1005a4);
- ram->fuc.r_0x100714 = ramfuc_reg(0x100714);
- ram->fuc.r_0x100718 = ramfuc_reg(0x100718);
- ram->fuc.r_0x10071c = ramfuc_reg(0x10071c);
- ram->fuc.r_0x100760 = ramfuc_reg(0x100760);
- ram->fuc.r_0x1007a0 = ramfuc_reg(0x1007a0);
- ram->fuc.r_0x1007e0 = ramfuc_reg(0x1007e0);
- ram->fuc.r_0x10f804 = ramfuc_reg(0x10f804);
- ram->fuc.r_0x1110e0 = ramfuc_reg(0x1110e0);
- ram->fuc.r_0x111100 = ramfuc_reg(0x111100);
- ram->fuc.r_0x111104 = ramfuc_reg(0x111104);
- ram->fuc.r_0x611200 = ramfuc_reg(0x611200);
-
- if (ram->base.ranks > 1) {
- ram->fuc.r_mr[0] = ramfuc_reg2(0x1002c0, 0x1002c8);
- ram->fuc.r_mr[1] = ramfuc_reg2(0x1002c4, 0x1002cc);
- ram->fuc.r_mr[2] = ramfuc_reg2(0x1002e0, 0x1002e8);
- ram->fuc.r_mr[3] = ramfuc_reg2(0x1002e4, 0x1002ec);
- } else {
- ram->fuc.r_mr[0] = ramfuc_reg(0x1002c0);
- ram->fuc.r_mr[1] = ramfuc_reg(0x1002c4);
- ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0);
- ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4);
- }
-
- return 0;
-}
-
-struct nouveau_oclass
-nva3_ram_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = nva3_ram_init,
- .fini = _nouveau_ram_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c
deleted file mode 100644
index 00f2ca7..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 "nv50.h"
-
-static int
-nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 datasize,
- struct nouveau_object **pobject)
-{
- const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
- const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
- 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;
-
- ram->size = nv_rd32(pfb, 0x10020c);
- ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32);
-
- ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) -
- (rsvd_head + rsvd_tail), 1);
- if (ret)
- return ret;
-
- ram->type = NV_MEM_TYPE_STOLEN;
- ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
- ram->get = nv50_ram_get;
- ram->put = nv50_ram_put;
- return 0;
-}
-
-struct nouveau_oclass
-nvaa_ram_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvaa_ram_ctor,
- .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
index f464547..cf97c4d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
@@ -23,414 +23,9 @@
*/
#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/pll.h>
-#include <subdev/bios/rammap.h>
-#include <subdev/bios/timing.h>
#include <subdev/ltcg.h>
-#include <subdev/clock.h>
-#include <subdev/clock/pll.h>
-
-#include <core/option.h>
-
-#include "ramfuc.h"
-
-#include "nvc0.h"
-
-struct nvc0_ramfuc {
- struct ramfuc base;
-
- struct ramfuc_reg r_0x10fe20;
- struct ramfuc_reg r_0x10fe24;
- struct ramfuc_reg r_0x137320;
- struct ramfuc_reg r_0x137330;
-
- struct ramfuc_reg r_0x132000;
- struct ramfuc_reg r_0x132004;
- struct ramfuc_reg r_0x132100;
-
- struct ramfuc_reg r_0x137390;
-
- struct ramfuc_reg r_0x10f290;
- struct ramfuc_reg r_0x10f294;
- struct ramfuc_reg r_0x10f298;
- struct ramfuc_reg r_0x10f29c;
- struct ramfuc_reg r_0x10f2a0;
-
- struct ramfuc_reg r_0x10f300;
- struct ramfuc_reg r_0x10f338;
- struct ramfuc_reg r_0x10f340;
- struct ramfuc_reg r_0x10f344;
- struct ramfuc_reg r_0x10f348;
-
- struct ramfuc_reg r_0x10f910;
- struct ramfuc_reg r_0x10f914;
-
- struct ramfuc_reg r_0x100b0c;
- struct ramfuc_reg r_0x10f050;
- struct ramfuc_reg r_0x10f090;
- struct ramfuc_reg r_0x10f200;
- struct ramfuc_reg r_0x10f210;
- struct ramfuc_reg r_0x10f310;
- struct ramfuc_reg r_0x10f314;
- struct ramfuc_reg r_0x10f610;
- struct ramfuc_reg r_0x10f614;
- struct ramfuc_reg r_0x10f800;
- struct ramfuc_reg r_0x10f808;
- struct ramfuc_reg r_0x10f824;
- struct ramfuc_reg r_0x10f830;
- struct ramfuc_reg r_0x10f988;
- struct ramfuc_reg r_0x10f98c;
- struct ramfuc_reg r_0x10f990;
- struct ramfuc_reg r_0x10f998;
- struct ramfuc_reg r_0x10f9b0;
- struct ramfuc_reg r_0x10f9b4;
- struct ramfuc_reg r_0x10fb04;
- struct ramfuc_reg r_0x10fb08;
- struct ramfuc_reg r_0x137300;
- struct ramfuc_reg r_0x137310;
- struct ramfuc_reg r_0x137360;
- struct ramfuc_reg r_0x1373ec;
- struct ramfuc_reg r_0x1373f0;
- struct ramfuc_reg r_0x1373f8;
-
- struct ramfuc_reg r_0x61c140;
- struct ramfuc_reg r_0x611200;
-
- struct ramfuc_reg r_0x13d8f4;
-};
-
-struct nvc0_ram {
- struct nouveau_ram base;
- struct nvc0_ramfuc fuc;
- struct nvbios_pll refpll;
- struct nvbios_pll mempll;
-};
-
-static void
-nvc0_ram_train(struct nvc0_ramfuc *fuc, u32 magic)
-{
- struct nvc0_ram *ram = container_of(fuc, typeof(*ram), fuc);
- struct nouveau_fb *pfb = nouveau_fb(ram);
- u32 part = nv_rd32(pfb, 0x022438), i;
- u32 mask = nv_rd32(pfb, 0x022554);
- u32 addr = 0x110974;
-
- ram_wr32(fuc, 0x10f910, magic);
- ram_wr32(fuc, 0x10f914, magic);
-
- for (i = 0; (magic & 0x80000000) && i < part; addr += 0x1000, i++) {
- if (mask & (1 << i))
- continue;
- ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
- }
-}
-
-static int
-nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
-{
- struct nouveau_clock *clk = nouveau_clock(pfb);
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nvc0_ram *ram = (void *)pfb->ram;
- struct nvc0_ramfuc *fuc = &ram->fuc;
- struct bit_entry M;
- u8 ver, cnt, strap;
- u32 data;
- struct {
- u32 data;
- u8 size;
- } rammap, ramcfg, timing;
- int ref, div, out;
- int from, mode;
- int N1, M1, P;
- int ret;
-
- /* lookup memory config data relevant to the target frequency */
- rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size,
- &cnt, &ramcfg.size);
- if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
- nv_error(pfb, "invalid/missing rammap entry\n");
- return -EINVAL;
- }
-
- /* locate specific data set for the attached memory */
- if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) {
- nv_error(pfb, "invalid/missing memory table\n");
- return -EINVAL;
- }
-
- strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
- data = nv_ro16(bios, M.offset + 1);
- if (data)
- strap = nv_ro08(bios, data + strap);
-
- if (strap >= cnt) {
- nv_error(pfb, "invalid ramcfg strap\n");
- return -EINVAL;
- }
-
- ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
- if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
- nv_error(pfb, "invalid/missing ramcfg entry\n");
- return -EINVAL;
- }
-
- /* lookup memory timings, if bios says they're present */
- strap = nv_ro08(bios, ramcfg.data + 0x01);
- if (strap != 0xff) {
- timing.data = nvbios_timing_entry(bios, strap, &ver,
- &timing.size);
- if (!timing.data || ver != 0x10 || timing.size < 0x19) {
- nv_error(pfb, "invalid/missing timing entry\n");
- return -EINVAL;
- }
- } else {
- timing.data = 0;
- }
-
- ret = ram_init(fuc, pfb);
- if (ret)
- return ret;
-
- /* determine current mclk configuration */
- from = !!(ram_rd32(fuc, 0x1373f0) & 0x00000002); /*XXX: ok? */
-
- /* determine target mclk configuration */
- if (!(ram_rd32(fuc, 0x137300) & 0x00000100))
- ref = clk->read(clk, nv_clk_src_sppll0);
- else
- ref = clk->read(clk, nv_clk_src_sppll1);
- div = max(min((ref * 2) / freq, (u32)65), (u32)2) - 2;
- out = (ref * 2) / (div + 2);
- mode = freq != out;
-
- ram_mask(fuc, 0x137360, 0x00000002, 0x00000000);
-
- if ((ram_rd32(fuc, 0x132000) & 0x00000002) || 0 /*XXX*/) {
- ram_nuke(fuc, 0x132000);
- ram_mask(fuc, 0x132000, 0x00000002, 0x00000002);
- ram_mask(fuc, 0x132000, 0x00000002, 0x00000000);
- }
-
- if (mode == 1) {
- ram_nuke(fuc, 0x10fe20);
- ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000002);
- ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000000);
- }
-
-// 0x00020034 // 0x0000000a
- ram_wr32(fuc, 0x132100, 0x00000001);
-
- if (mode == 1 && from == 0) {
- /* calculate refpll */
- ret = nva3_pll_calc(nv_subdev(pfb), &ram->refpll,
- ram->mempll.refclk, &N1, NULL, &M1, &P);
- if (ret <= 0) {
- nv_error(pfb, "unable to calc refpll\n");
- return ret ? ret : -ERANGE;
- }
-
- ram_wr32(fuc, 0x10fe20, 0x20010000);
- ram_wr32(fuc, 0x137320, 0x00000003);
- ram_wr32(fuc, 0x137330, 0x81200006);
- ram_wr32(fuc, 0x10fe24, (P << 16) | (N1 << 8) | M1);
- ram_wr32(fuc, 0x10fe20, 0x20010001);
- ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
-
- /* calculate mempll */
- ret = nva3_pll_calc(nv_subdev(pfb), &ram->mempll, freq,
- &N1, NULL, &M1, &P);
- if (ret <= 0) {
- nv_error(pfb, "unable to calc refpll\n");
- return ret ? ret : -ERANGE;
- }
-
- ram_wr32(fuc, 0x10fe20, 0x20010005);
- ram_wr32(fuc, 0x132004, (P << 16) | (N1 << 8) | M1);
- ram_wr32(fuc, 0x132000, 0x18010101);
- ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000);
- } else
- if (mode == 0) {
- ram_wr32(fuc, 0x137300, 0x00000003);
- }
-
- if (from == 0) {
- ram_nuke(fuc, 0x10fb04);
- ram_mask(fuc, 0x10fb04, 0x0000ffff, 0x00000000);
- ram_nuke(fuc, 0x10fb08);
- ram_mask(fuc, 0x10fb08, 0x0000ffff, 0x00000000);
- ram_wr32(fuc, 0x10f988, 0x2004ff00);
- ram_wr32(fuc, 0x10f98c, 0x003fc040);
- ram_wr32(fuc, 0x10f990, 0x20012001);
- ram_wr32(fuc, 0x10f998, 0x00011a00);
- ram_wr32(fuc, 0x13d8f4, 0x00000000);
- } else {
- ram_wr32(fuc, 0x10f988, 0x20010000);
- ram_wr32(fuc, 0x10f98c, 0x00000000);
- ram_wr32(fuc, 0x10f990, 0x20012001);
- ram_wr32(fuc, 0x10f998, 0x00010a00);
- }
-
- if (from == 0) {
-// 0x00020039 // 0x000000ba
- }
-
-// 0x0002003a // 0x00000002
- ram_wr32(fuc, 0x100b0c, 0x00080012);
-// 0x00030014 // 0x00000000 // 0x02b5f070
-// 0x00030014 // 0x00010000 // 0x02b5f070
- ram_wr32(fuc, 0x611200, 0x00003300);
-// 0x00020034 // 0x0000000a
-// 0x00030020 // 0x00000001 // 0x00000000
-
- ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
- ram_wr32(fuc, 0x10f210, 0x00000000);
- ram_nsec(fuc, 1000);
- if (mode == 0)
- nvc0_ram_train(fuc, 0x000c1001);
- ram_wr32(fuc, 0x10f310, 0x00000001);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f090, 0x00000061);
- ram_wr32(fuc, 0x10f090, 0xc000007f);
- ram_nsec(fuc, 1000);
-
- if (from == 0) {
- ram_wr32(fuc, 0x10f824, 0x00007fd4);
- } else {
- ram_wr32(fuc, 0x1373ec, 0x00020404);
- }
-
- if (mode == 0) {
- ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000);
- ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000);
- ram_wr32(fuc, 0x10f830, 0x41500010);
- ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
- ram_mask(fuc, 0x132100, 0x00000100, 0x00000100);
- ram_wr32(fuc, 0x10f050, 0xff000090);
- ram_wr32(fuc, 0x1373ec, 0x00020f0f);
- ram_wr32(fuc, 0x1373f0, 0x00000003);
- ram_wr32(fuc, 0x137310, 0x81201616);
- ram_wr32(fuc, 0x132100, 0x00000001);
-// 0x00020039 // 0x000000ba
- ram_wr32(fuc, 0x10f830, 0x00300017);
- ram_wr32(fuc, 0x1373f0, 0x00000001);
- ram_wr32(fuc, 0x10f824, 0x00007e77);
- ram_wr32(fuc, 0x132000, 0x18030001);
- ram_wr32(fuc, 0x10f090, 0x4000007e);
- ram_nsec(fuc, 2000);
- ram_wr32(fuc, 0x10f314, 0x00000001);
- ram_wr32(fuc, 0x10f210, 0x80000000);
- ram_wr32(fuc, 0x10f338, 0x00300220);
- ram_wr32(fuc, 0x10f300, 0x0000011d);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f290, 0x02060505);
- ram_wr32(fuc, 0x10f294, 0x34208288);
- ram_wr32(fuc, 0x10f298, 0x44050411);
- ram_wr32(fuc, 0x10f29c, 0x0000114c);
- ram_wr32(fuc, 0x10f2a0, 0x42e10069);
- ram_wr32(fuc, 0x10f614, 0x40044f77);
- ram_wr32(fuc, 0x10f610, 0x40044f77);
- ram_wr32(fuc, 0x10f344, 0x00600009);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f348, 0x00700008);
- ram_wr32(fuc, 0x61c140, 0x19240000);
- ram_wr32(fuc, 0x10f830, 0x00300017);
- nvc0_ram_train(fuc, 0x80021001);
- nvc0_ram_train(fuc, 0x80081001);
- ram_wr32(fuc, 0x10f340, 0x00500004);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f830, 0x01300017);
- ram_wr32(fuc, 0x10f830, 0x00300017);
-// 0x00030020 // 0x00000000 // 0x00000000
-// 0x00020034 // 0x0000000b
- ram_wr32(fuc, 0x100b0c, 0x00080028);
- ram_wr32(fuc, 0x611200, 0x00003330);
- } else {
- ram_wr32(fuc, 0x10f800, 0x00001800);
- ram_wr32(fuc, 0x13d8f4, 0x00000000);
- ram_wr32(fuc, 0x1373ec, 0x00020404);
- ram_wr32(fuc, 0x1373f0, 0x00000003);
- ram_wr32(fuc, 0x10f830, 0x40700010);
- ram_wr32(fuc, 0x10f830, 0x40500010);
- ram_wr32(fuc, 0x13d8f4, 0x00000000);
- ram_wr32(fuc, 0x1373f8, 0x00000000);
- ram_wr32(fuc, 0x132100, 0x00000101);
- ram_wr32(fuc, 0x137310, 0x89201616);
- ram_wr32(fuc, 0x10f050, 0xff000090);
- ram_wr32(fuc, 0x1373ec, 0x00030404);
- ram_wr32(fuc, 0x1373f0, 0x00000002);
- // 0x00020039 // 0x00000011
- ram_wr32(fuc, 0x132100, 0x00000001);
- ram_wr32(fuc, 0x1373f8, 0x00002000);
- ram_nsec(fuc, 2000);
- ram_wr32(fuc, 0x10f808, 0x7aaa0050);
- ram_wr32(fuc, 0x10f830, 0x00500010);
- ram_wr32(fuc, 0x10f200, 0x00ce1000);
- ram_wr32(fuc, 0x10f090, 0x4000007e);
- ram_nsec(fuc, 2000);
- ram_wr32(fuc, 0x10f314, 0x00000001);
- ram_wr32(fuc, 0x10f210, 0x80000000);
- ram_wr32(fuc, 0x10f338, 0x00300200);
- ram_wr32(fuc, 0x10f300, 0x0000084d);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f290, 0x0b343825);
- ram_wr32(fuc, 0x10f294, 0x3483028e);
- ram_wr32(fuc, 0x10f298, 0x440c0600);
- ram_wr32(fuc, 0x10f29c, 0x0000214c);
- ram_wr32(fuc, 0x10f2a0, 0x42e20069);
- ram_wr32(fuc, 0x10f200, 0x00ce0000);
- ram_wr32(fuc, 0x10f614, 0x60044e77);
- ram_wr32(fuc, 0x10f610, 0x60044e77);
- ram_wr32(fuc, 0x10f340, 0x00500000);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f344, 0x00600228);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f348, 0x00700000);
- ram_wr32(fuc, 0x13d8f4, 0x00000000);
- ram_wr32(fuc, 0x61c140, 0x09a40000);
-
- nvc0_ram_train(fuc, 0x800e1008);
-
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f800, 0x00001804);
- // 0x00030020 // 0x00000000 // 0x00000000
- // 0x00020034 // 0x0000000b
- ram_wr32(fuc, 0x13d8f4, 0x00000000);
- ram_wr32(fuc, 0x100b0c, 0x00080028);
- ram_wr32(fuc, 0x611200, 0x00003330);
- ram_nsec(fuc, 100000);
- ram_wr32(fuc, 0x10f9b0, 0x05313f41);
- ram_wr32(fuc, 0x10f9b4, 0x00002f50);
-
- nvc0_ram_train(fuc, 0x010c1001);
- }
-
- ram_mask(fuc, 0x10f200, 0x00000800, 0x00000800);
-// 0x00020016 // 0x00000000
-
- if (mode == 0)
- ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
- return 0;
-}
-
-static int
-nvc0_ram_prog(struct nouveau_fb *pfb)
-{
- struct nouveau_device *device = nv_device(pfb);
- struct nvc0_ram *ram = (void *)pfb->ram;
- struct nvc0_ramfuc *fuc = &ram->fuc;
- ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
- return 0;
-}
-
-static void
-nvc0_ram_tidy(struct nouveau_fb *pfb)
-{
- struct nvc0_ram *ram = (void *)pfb->ram;
- struct nvc0_ramfuc *fuc = &ram->fuc;
- ram_exec(fuc, false);
-}
+#include "priv.h"
extern const u8 nvc0_pte_storage_type_map[256];
@@ -515,9 +110,10 @@ nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
return 0;
}
-int
-nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int size, void **pobject)
+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);
@@ -531,8 +127,8 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
bool uniform = true;
int ret, part;
- ret = nouveau_ram_create_(parent, engine, oclass, size, pobject);
- ram = *pobject;
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
if (ret)
return ret;
@@ -586,158 +182,13 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-static int
-nvc0_ram_init(struct nouveau_object *object)
-{
- struct nouveau_fb *pfb = (void *)object->parent;
- struct nvc0_ram *ram = (void *)object;
- int ret, i;
-
- ret = nouveau_ram_init(&ram->base);
- if (ret)
- return ret;
-
- /* prepare for ddr link training, and load training patterns */
- switch (ram->base.type) {
- case NV_MEM_TYPE_GDDR5: {
- static const u8 train0[] = {
- 0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
- 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
- };
- static const u32 train1[] = {
- 0x00000000, 0xffffffff,
- 0x55555555, 0xaaaaaaaa,
- 0x33333333, 0xcccccccc,
- 0xf0f0f0f0, 0x0f0f0f0f,
- 0x00ff00ff, 0xff00ff00,
- 0x0000ffff, 0xffff0000,
- };
-
- for (i = 0; i < 0x30; i++) {
- nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8));
- nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8));
- nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]);
- nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]);
- nv_wr32(pfb, 0x10f918, train1[i % 12]);
- nv_wr32(pfb, 0x10f91c, train1[i % 12]);
- nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]);
- nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]);
- nv_wr32(pfb, 0x10f918, train1[i % 12]);
- nv_wr32(pfb, 0x10f91c, train1[i % 12]);
- }
- } break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int
-nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nvc0_ram *ram;
- int ret;
-
- ret = nvc0_ram_create(parent, engine, oclass, &ram);
- *pobject = nv_object(ram);
- if (ret)
- return ret;
-
- ret = nvbios_pll_parse(bios, 0x0c, &ram->refpll);
- if (ret) {
- nv_error(ram, "mclk refpll data not found\n");
- return ret;
- }
-
- ret = nvbios_pll_parse(bios, 0x04, &ram->mempll);
- if (ret) {
- nv_error(ram, "mclk pll data not found\n");
- return ret;
- }
-
- switch (ram->base.type) {
- case NV_MEM_TYPE_GDDR5:
- ram->base.calc = nvc0_ram_calc;
- ram->base.prog = nvc0_ram_prog;
- ram->base.tidy = nvc0_ram_tidy;
- break;
- default:
- nv_warn(ram, "reclocking of this ram type unsupported\n");
- return 0;
- }
-
- ram->fuc.r_0x10fe20 = ramfuc_reg(0x10fe20);
- ram->fuc.r_0x10fe24 = ramfuc_reg(0x10fe24);
- ram->fuc.r_0x137320 = ramfuc_reg(0x137320);
- ram->fuc.r_0x137330 = ramfuc_reg(0x137330);
-
- ram->fuc.r_0x132000 = ramfuc_reg(0x132000);
- ram->fuc.r_0x132004 = ramfuc_reg(0x132004);
- ram->fuc.r_0x132100 = ramfuc_reg(0x132100);
-
- ram->fuc.r_0x137390 = ramfuc_reg(0x137390);
-
- ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
- ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
- ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
- ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
- ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
-
- ram->fuc.r_0x10f300 = ramfuc_reg(0x10f300);
- ram->fuc.r_0x10f338 = ramfuc_reg(0x10f338);
- ram->fuc.r_0x10f340 = ramfuc_reg(0x10f340);
- ram->fuc.r_0x10f344 = ramfuc_reg(0x10f344);
- ram->fuc.r_0x10f348 = ramfuc_reg(0x10f348);
-
- ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
- ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
-
- ram->fuc.r_0x100b0c = ramfuc_reg(0x100b0c);
- ram->fuc.r_0x10f050 = ramfuc_reg(0x10f050);
- ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090);
- ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200);
- ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210);
- ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310);
- ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314);
- ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610);
- ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614);
- ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800);
- ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808);
- ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824);
- ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830);
- ram->fuc.r_0x10f988 = ramfuc_reg(0x10f988);
- ram->fuc.r_0x10f98c = ramfuc_reg(0x10f98c);
- ram->fuc.r_0x10f990 = ramfuc_reg(0x10f990);
- ram->fuc.r_0x10f998 = ramfuc_reg(0x10f998);
- ram->fuc.r_0x10f9b0 = ramfuc_reg(0x10f9b0);
- ram->fuc.r_0x10f9b4 = ramfuc_reg(0x10f9b4);
- ram->fuc.r_0x10fb04 = ramfuc_reg(0x10fb04);
- ram->fuc.r_0x10fb08 = ramfuc_reg(0x10fb08);
- ram->fuc.r_0x137310 = ramfuc_reg(0x137300);
- ram->fuc.r_0x137310 = ramfuc_reg(0x137310);
- ram->fuc.r_0x137360 = ramfuc_reg(0x137360);
- ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec);
- ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0);
- ram->fuc.r_0x1373f8 = ramfuc_reg(0x1373f8);
-
- ram->fuc.r_0x61c140 = ramfuc_reg(0x61c140);
- ram->fuc.r_0x611200 = ramfuc_reg(0x611200);
-
- ram->fuc.r_0x13d8f4 = ramfuc_reg(0x13d8f4);
- return 0;
-}
-
struct nouveau_oclass
nvc0_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_ram_ctor,
+ .ctor = nvc0_ram_create,
.dtor = _nouveau_ram_dtor,
- .init = nvc0_ram_init,
+ .init = _nouveau_ram_init,
.fini = _nouveau_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
deleted file mode 100644
index bc86cfd..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
+++ /dev/null
@@ -1,1264 +0,0 @@
-/*
- * 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/gpio.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/pll.h>
-#include <subdev/bios/init.h>
-#include <subdev/bios/rammap.h>
-#include <subdev/bios/timing.h>
-
-#include <subdev/clock.h>
-#include <subdev/clock/pll.h>
-
-#include <subdev/timer.h>
-
-#include <core/option.h>
-
-#include "nvc0.h"
-
-#include "ramfuc.h"
-
-struct nve0_ramfuc {
- struct ramfuc base;
-
- struct nvbios_pll refpll;
- struct nvbios_pll mempll;
-
- struct ramfuc_reg r_gpioMV;
- u32 r_funcMV[2];
- struct ramfuc_reg r_gpio2E;
- u32 r_func2E[2];
- struct ramfuc_reg r_gpiotrig;
-
- struct ramfuc_reg r_0x132020;
- struct ramfuc_reg r_0x132028;
- struct ramfuc_reg r_0x132024;
- struct ramfuc_reg r_0x132030;
- struct ramfuc_reg r_0x132034;
- struct ramfuc_reg r_0x132000;
- struct ramfuc_reg r_0x132004;
- struct ramfuc_reg r_0x132040;
-
- struct ramfuc_reg r_0x10f248;
- struct ramfuc_reg r_0x10f290;
- struct ramfuc_reg r_0x10f294;
- struct ramfuc_reg r_0x10f298;
- struct ramfuc_reg r_0x10f29c;
- struct ramfuc_reg r_0x10f2a0;
- struct ramfuc_reg r_0x10f2a4;
- struct ramfuc_reg r_0x10f2a8;
- struct ramfuc_reg r_0x10f2ac;
- struct ramfuc_reg r_0x10f2cc;
- struct ramfuc_reg r_0x10f2e8;
- struct ramfuc_reg r_0x10f250;
- struct ramfuc_reg r_0x10f24c;
- struct ramfuc_reg r_0x10fec4;
- struct ramfuc_reg r_0x10fec8;
- struct ramfuc_reg r_0x10f604;
- struct ramfuc_reg r_0x10f614;
- struct ramfuc_reg r_0x10f610;
- struct ramfuc_reg r_0x100770;
- struct ramfuc_reg r_0x100778;
- struct ramfuc_reg r_0x10f224;
-
- struct ramfuc_reg r_0x10f870;
- struct ramfuc_reg r_0x10f698;
- struct ramfuc_reg r_0x10f694;
- struct ramfuc_reg r_0x10f6b8;
- struct ramfuc_reg r_0x10f808;
- struct ramfuc_reg r_0x10f670;
- struct ramfuc_reg r_0x10f60c;
- struct ramfuc_reg r_0x10f830;
- struct ramfuc_reg r_0x1373ec;
- struct ramfuc_reg r_0x10f800;
- struct ramfuc_reg r_0x10f82c;
-
- struct ramfuc_reg r_0x10f978;
- struct ramfuc_reg r_0x10f910;
- struct ramfuc_reg r_0x10f914;
-
- struct ramfuc_reg r_mr[16]; /* MR0 - MR8, MR15 */
-
- struct ramfuc_reg r_0x62c000;
- struct ramfuc_reg r_0x10f200;
- struct ramfuc_reg r_0x10f210;
- struct ramfuc_reg r_0x10f310;
- struct ramfuc_reg r_0x10f314;
- struct ramfuc_reg r_0x10f318;
- struct ramfuc_reg r_0x10f090;
- struct ramfuc_reg r_0x10f69c;
- struct ramfuc_reg r_0x10f824;
- struct ramfuc_reg r_0x1373f0;
- struct ramfuc_reg r_0x1373f4;
- struct ramfuc_reg r_0x137320;
- struct ramfuc_reg r_0x10f65c;
- struct ramfuc_reg r_0x10f6bc;
- struct ramfuc_reg r_0x100710;
- struct ramfuc_reg r_0x10f750;
-};
-
-struct nve0_ram {
- struct nouveau_ram base;
- struct nve0_ramfuc fuc;
- int from;
- int mode;
- int N1, fN1, M1, P1;
- int N2, M2, P2;
-};
-
-/*******************************************************************************
- * GDDR5
- ******************************************************************************/
-static void
-train(struct nve0_ramfuc *fuc, u32 magic)
-{
- struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
- struct nouveau_fb *pfb = nouveau_fb(ram);
- const int mc = nv_rd32(pfb, 0x02243c);
- int i;
-
- ram_mask(fuc, 0x10f910, 0xbc0e0000, magic);
- ram_mask(fuc, 0x10f914, 0xbc0e0000, magic);
- for (i = 0; i < mc; i++) {
- const u32 addr = 0x110974 + (i * 0x1000);
- ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
- }
-}
-
-static void
-r1373f4_init(struct nve0_ramfuc *fuc)
-{
- struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
- const u32 mcoef = ((--ram->P2 << 28) | (ram->N2 << 8) | ram->M2);
- const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
- const u32 runk0 = ram->fN1 << 16;
- const u32 runk1 = ram->fN1;
-
- if (ram->from == 2) {
- ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
- ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
- } else {
- ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
- }
-
- ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
- ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
-
- /* (re)program refpll, if required */
- if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
- (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
- ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
- ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
- ram_wr32(fuc, 0x137320, 0x00000000);
- ram_mask(fuc, 0x132030, 0xffff0000, runk0);
- ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
- ram_wr32(fuc, 0x132024, rcoef);
- ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
- ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
- ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
- ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
- }
-
- /* (re)program mempll, if required */
- if (ram->mode == 2) {
- ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
- ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
- ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
- ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
- ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000);
- ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
- } else {
- ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010100);
- }
-
- ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
-}
-
-static void
-r1373f4_fini(struct nve0_ramfuc *fuc, u32 ramcfg)
-{
- struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
- struct nouveau_bios *bios = nouveau_bios(ram);
- u8 v0 = (nv_ro08(bios, ramcfg + 0x03) & 0xc0) >> 6;
- u8 v1 = (nv_ro08(bios, ramcfg + 0x03) & 0x30) >> 4;
- u32 tmp;
-
- tmp = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
- ram_wr32(fuc, 0x1373ec, tmp | (v1 << 16));
- ram_mask(fuc, 0x1373f0, (~ram->mode & 3), 0x00000000);
- if (ram->mode == 2) {
- ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000002);
- ram_mask(fuc, 0x1373f4, 0x00001100, 0x000000000);
- } else {
- ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000001);
- ram_mask(fuc, 0x1373f4, 0x00010000, 0x000000000);
- }
- ram_mask(fuc, 0x10f800, 0x00000030, (v0 ^ v1) << 4);
-}
-
-static int
-nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
- const u32 rammap = ram->base.rammap.data;
- const u32 ramcfg = ram->base.ramcfg.data;
- const u32 timing = ram->base.timing.data;
- int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08);
- int mv = 1; /*XXX*/
- u32 mask, data;
-
- ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
- ram_wr32(fuc, 0x62c000, 0x0f0f0000);
-
- /* MR1: turn termination on early, for some reason.. */
- if ((ram->base.mr[1] & 0x03c) != 0x030)
- ram_mask(fuc, mr[1], 0x03c, ram->base.mr[1] & 0x03c);
-
- if (vc == 1 && ram_have(fuc, gpio2E)) {
- u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
- if (temp != ram_rd32(fuc, gpio2E)) {
- ram_wr32(fuc, gpiotrig, 1);
- ram_nsec(fuc, 20000);
- }
- }
-
- ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
-
- ram_mask(fuc, 0x10f914, 0x01020000, 0x000c0000);
- ram_mask(fuc, 0x10f910, 0x01020000, 0x000c0000);
-
- ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
- ram_nsec(fuc, 1000);
-
- ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
- ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
- ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
- ram_wr32(fuc, 0x10f090, 0x00000061);
- ram_wr32(fuc, 0x10f090, 0xc000007f);
- ram_nsec(fuc, 1000);
-
- ram_wr32(fuc, 0x10f698, 0x00000000);
- ram_wr32(fuc, 0x10f69c, 0x00000000);
-
- /*XXX: there does appear to be some kind of condition here, simply
- * modifying these bits in the vbios from the default pl0
- * entries shows no change. however, the data does appear to
- * be correct and may be required for the transition back
- */
- mask = 0x800f07e0;
- data = 0x00030000;
- if (ram_rd32(fuc, 0x10f978) & 0x00800000)
- data |= 0x00040000;
-
- if (1) {
- data |= 0x800807e0;
- switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) {
- case 0xc0: data &= ~0x00000040; break;
- case 0x80: data &= ~0x00000100; break;
- case 0x40: data &= ~0x80000000; break;
- case 0x00: data &= ~0x00000400; break;
- }
-
- switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) {
- case 0x30: data &= ~0x00000020; break;
- case 0x20: data &= ~0x00000080; break;
- case 0x10: data &= ~0x00080000; break;
- case 0x00: data &= ~0x00000200; break;
- }
- }
-
- if (nv_ro08(bios, ramcfg + 0x02) & 0x80)
- mask |= 0x03000000;
- if (nv_ro08(bios, ramcfg + 0x02) & 0x40)
- mask |= 0x00002000;
- if (nv_ro08(bios, ramcfg + 0x07) & 0x10)
- mask |= 0x00004000;
- if (nv_ro08(bios, ramcfg + 0x07) & 0x08)
- mask |= 0x00000003;
- else {
- mask |= 0x34000000;
- if (ram_rd32(fuc, 0x10f978) & 0x00800000)
- mask |= 0x40000000;
- }
- ram_mask(fuc, 0x10f824, mask, data);
-
- ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
-
- if (ram->from == 2 && ram->mode != 2) {
- ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000);
- ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000);
- ram_mask(fuc, 0x10f800, 0x00000000, 0x00000004);
- ram_mask(fuc, 0x10f830, 0x00008000, 0x01040010);
- ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
- r1373f4_init(fuc);
- ram_mask(fuc, 0x1373f0, 0x00000002, 0x00000001);
- r1373f4_fini(fuc, ramcfg);
- ram_mask(fuc, 0x10f830, 0x00c00000, 0x00240001);
- } else
- if (ram->from != 2 && ram->mode != 2) {
- r1373f4_init(fuc);
- r1373f4_fini(fuc, ramcfg);
- }
-
- if (ram_have(fuc, gpioMV)) {
- u32 temp = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
- if (temp != ram_rd32(fuc, gpioMV)) {
- ram_wr32(fuc, gpiotrig, 1);
- ram_nsec(fuc, 64000);
- }
- }
-
- if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) ||
- (nv_ro08(bios, ramcfg + 0x07) & 0x10)) {
- ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
- ram_nsec(fuc, 20000);
- }
-
- if (ram->from != 2 && ram->mode == 2) {
- ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
- ram_mask(fuc, 0x1373f0, 0x00000000, 0x00000002);
- ram_mask(fuc, 0x10f830, 0x00800001, 0x00408010);
- r1373f4_init(fuc);
- r1373f4_fini(fuc, ramcfg);
- ram_mask(fuc, 0x10f808, 0x00000000, 0x00080000);
- ram_mask(fuc, 0x10f200, 0x00808000, 0x00800000);
- } else
- if (ram->from == 2 && ram->mode == 2) {
- ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
- r1373f4_init(fuc);
- r1373f4_fini(fuc, ramcfg);
- }
-
- if (ram->mode != 2) /*XXX*/ {
- if (nv_ro08(bios, ramcfg + 0x07) & 0x40)
- ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
- }
-
- data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2;
- ram_wr32(fuc, 0x10f65c, 0x00000011 * data);
- ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
- ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
-
- data = nv_ro08(bios, ramcfg + 0x04);
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
- ram_wr32(fuc, 0x10f698, 0x01010101 * data);
- ram_wr32(fuc, 0x10f69c, 0x01010101 * data);
- }
-
- if (ram->mode != 2) {
- u32 temp = ram_rd32(fuc, 0x10f694) & ~0xff00ff00;
- ram_wr32(fuc, 0x10f694, temp | (0x01000100 * data));
- }
-
- if (ram->mode == 2 && (nv_ro08(bios, ramcfg + 0x08) & 0x10))
- data = 0x00000080;
- else
- data = 0x00000000;
- ram_mask(fuc, 0x10f60c, 0x00000080, data);
-
- mask = 0x00070000;
- data = 0x00000000;
- if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80))
- data |= 0x03000000;
- if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40))
- data |= 0x00002000;
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10))
- data |= 0x00004000;
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08))
- data |= 0x00000003;
- else
- data |= 0x74000000;
- ram_mask(fuc, 0x10f824, mask, data);
-
- if (nv_ro08(bios, ramcfg + 0x01) & 0x08)
- data = 0x00000000;
- else
- data = 0x00001000;
- ram_mask(fuc, 0x10f200, 0x00001000, data);
-
- if (ram_rd32(fuc, 0x10f670) & 0x80000000) {
- ram_nsec(fuc, 10000);
- ram_mask(fuc, 0x10f670, 0x80000000, 0x00000000);
- }
-
- if (nv_ro08(bios, ramcfg + 0x08) & 0x01)
- data = 0x00100000;
- else
- data = 0x00000000;
- ram_mask(fuc, 0x10f82c, 0x00100000, data);
-
- data = 0x00000000;
- if (nv_ro08(bios, ramcfg + 0x08) & 0x08)
- data |= 0x00002000;
- if (nv_ro08(bios, ramcfg + 0x08) & 0x04)
- data |= 0x00001000;
- if (nv_ro08(bios, ramcfg + 0x08) & 0x02)
- data |= 0x00004000;
- ram_mask(fuc, 0x10f830, 0x00007000, data);
-
- /* PFB timing */
- ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28));
- ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00));
- ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04));
- ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08));
- ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c));
- ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10));
- ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14));
- ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18));
- ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c));
- ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20));
- ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24));
-
- data = (nv_ro08(bios, ramcfg + 0x02) & 0x03) << 8;
- if (nv_ro08(bios, ramcfg + 0x01) & 0x10)
- data |= 0x70000000;
- ram_mask(fuc, 0x10f604, 0x70000300, data);
-
- data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28;
- if (nv_ro08(bios, ramcfg + 0x01) & 0x01)
- data |= 0x00000100;
- ram_mask(fuc, 0x10f614, 0x70000000, data);
-
- data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28;
- if (nv_ro08(bios, ramcfg + 0x01) & 0x02)
- data |= 0x00000100;
- ram_mask(fuc, 0x10f610, 0x70000000, data);
-
- mask = 0x33f00000;
- data = 0x00000000;
- if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04))
- data |= 0x20200000;
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
- data |= 0x12800000;
- /*XXX: see note above about there probably being some condition
- * for the 10f824 stuff that uses ramcfg 3...
- */
- if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) {
- if (nv_ro08(bios, rammap + 0x08) & 0x0c) {
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
- mask |= 0x00000020;
- else
- data |= 0x00000020;
- mask |= 0x00000004;
- }
- } else {
- mask |= 0x40000020;
- data |= 0x00000004;
- }
-
- ram_mask(fuc, 0x10f808, mask, data);
-
- data = nv_ro08(bios, ramcfg + 0x03) & 0x0f;
- ram_wr32(fuc, 0x10f870, 0x11111111 * data);
-
- data = nv_ro08(bios, ramcfg + 0x02) & 0x03;
- if (nv_ro08(bios, ramcfg + 0x01) & 0x10)
- data |= 0x00000004;
- if ((nv_rd32(bios, 0x100770) & 0x00000004) != (data & 0x00000004)) {
- ram_wr32(fuc, 0x10f750, 0x04000009);
- ram_wr32(fuc, 0x100710, 0x00000000);
- ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000);
- }
- ram_mask(fuc, 0x100770, 0x00000007, data);
-
- data = (nv_ro08(bios, timing + 0x30) & 0x07) << 8;
- if (nv_ro08(bios, ramcfg + 0x01) & 0x01)
- data |= 0x80000000;
- ram_mask(fuc, 0x100778, 0x00000700, data);
-
- data = nv_ro16(bios, timing + 0x2c);
- ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4);
- ram_mask(fuc, 0x10f24c, 0x7f000000, (data & 0x1fc0) << 18);
-
- data = nv_ro08(bios, timing + 0x30);
- ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
-
- data = nv_ro16(bios, timing + 0x31);
- ram_mask(fuc, 0x10fec4, 0x041e0f07, (data & 0x0800) << 15 |
- (data & 0x0780) << 10 |
- (data & 0x0078) << 5 |
- (data & 0x0007));
- ram_mask(fuc, 0x10fec8, 0x00000027, (data & 0x8000) >> 10 |
- (data & 0x7000) >> 12);
-
- ram_wr32(fuc, 0x10f090, 0x4000007e);
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
- ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
- ram_nsec(fuc, 2000);
- ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
-
- if ((nv_ro08(bios, ramcfg + 0x08) & 0x10) && (ram->mode == 2) /*XXX*/) {
- u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000);
- train(fuc, 0xa4010000); /*XXX*/
- ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f294, temp);
- }
-
- ram_mask(fuc, mr[3], 0xfff, ram->base.mr[3]);
- ram_wr32(fuc, mr[0], ram->base.mr[0]);
- ram_mask(fuc, mr[8], 0xfff, ram->base.mr[8]);
- ram_nsec(fuc, 1000);
- ram_mask(fuc, mr[1], 0xfff, ram->base.mr[1]);
- ram_mask(fuc, mr[5], 0xfff, ram->base.mr[5]);
- ram_mask(fuc, mr[6], 0xfff, ram->base.mr[6]);
- ram_mask(fuc, mr[7], 0xfff, ram->base.mr[7]);
-
- if (vc == 0 && ram_have(fuc, gpio2E)) {
- u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
- if (temp != ram_rd32(fuc, gpio2E)) {
- ram_wr32(fuc, gpiotrig, 1);
- ram_nsec(fuc, 20000);
- }
- }
-
- ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
- ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
- ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
- ram_nsec(fuc, 1000);
-
- data = ram_rd32(fuc, 0x10f978);
- data &= ~0x00046144;
- data |= 0x0000000b;
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x04))
- data |= 0x0000200c;
- else
- data |= 0x00000000;
- } else {
- data |= 0x00040044;
- }
- ram_wr32(fuc, 0x10f978, data);
-
- if (ram->mode == 1) {
- data = ram_rd32(fuc, 0x10f830) | 0x00000001;
- ram_wr32(fuc, 0x10f830, data);
- }
-
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
- data = 0x88020000;
- if ( (nv_ro08(bios, ramcfg + 0x07) & 0x04))
- data |= 0x10000000;
- if (!(nv_ro08(bios, rammap + 0x08) & 0x10))
- data |= 0x00080000;
- } else {
- data = 0xa40e0000;
- }
- train(fuc, data);
- ram_nsec(fuc, 1000);
-
- if (ram->mode == 2) { /*XXX*/
- ram_mask(fuc, 0x10f800, 0x00000004, 0x00000004);
- }
-
- /* MR5: (re)enable LP3 if necessary
- * XXX: need to find the switch, keeping off for now
- */
- ram_mask(fuc, mr[5], 0x00000004, 0x00000000);
-
- if (ram->mode != 2) {
- ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
- ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
- }
-
- if (nv_ro08(bios, ramcfg + 0x07) & 0x02) {
- ram_mask(fuc, 0x10f910, 0x80020000, 0x01000000);
- ram_mask(fuc, 0x10f914, 0x80020000, 0x01000000);
- }
-
- ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
-
- if (nv_ro08(bios, rammap + 0x08) & 0x01)
- data = 0x00000800;
- else
- data = 0x00000000;
- ram_mask(fuc, 0x10f200, 0x00000800, data);
- return 0;
-}
-
-/*******************************************************************************
- * DDR3
- ******************************************************************************/
-
-static int
-nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
- const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
- const u32 runk0 = ram->fN1 << 16;
- const u32 runk1 = ram->fN1;
- const u32 rammap = ram->base.rammap.data;
- const u32 ramcfg = ram->base.ramcfg.data;
- const u32 timing = ram->base.timing.data;
- int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08);
- int mv = 1; /*XXX*/
- u32 mask, data;
-
- ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
- ram_wr32(fuc, 0x62c000, 0x0f0f0000);
-
- if (vc == 1 && ram_have(fuc, gpio2E)) {
- u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
- if (temp != ram_rd32(fuc, gpio2E)) {
- ram_wr32(fuc, gpiotrig, 1);
- ram_nsec(fuc, 20000);
- }
- }
-
- ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
- if ((nv_ro08(bios, ramcfg + 0x03) & 0xf0))
- ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
-
- ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
- ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
- ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
- ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
- ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
- ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
- ram_nsec(fuc, 1000);
-
- ram_wr32(fuc, 0x10f090, 0x00000060);
- ram_wr32(fuc, 0x10f090, 0xc000007e);
-
- /*XXX: there does appear to be some kind of condition here, simply
- * modifying these bits in the vbios from the default pl0
- * entries shows no change. however, the data does appear to
- * be correct and may be required for the transition back
- */
- mask = 0x00010000;
- data = 0x00010000;
-
- if (1) {
- mask |= 0x800807e0;
- data |= 0x800807e0;
- switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) {
- case 0xc0: data &= ~0x00000040; break;
- case 0x80: data &= ~0x00000100; break;
- case 0x40: data &= ~0x80000000; break;
- case 0x00: data &= ~0x00000400; break;
- }
-
- switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) {
- case 0x30: data &= ~0x00000020; break;
- case 0x20: data &= ~0x00000080; break;
- case 0x10: data &= ~0x00080000; break;
- case 0x00: data &= ~0x00000200; break;
- }
- }
-
- if (nv_ro08(bios, ramcfg + 0x02) & 0x80)
- mask |= 0x03000000;
- if (nv_ro08(bios, ramcfg + 0x02) & 0x40)
- mask |= 0x00002000;
- if (nv_ro08(bios, ramcfg + 0x07) & 0x10)
- mask |= 0x00004000;
- if (nv_ro08(bios, ramcfg + 0x07) & 0x08)
- mask |= 0x00000003;
- else
- mask |= 0x14000000;
- ram_mask(fuc, 0x10f824, mask, data);
-
- ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
-
- ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
- data = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
- data |= (nv_ro08(bios, ramcfg + 0x03) & 0x30) << 12;
- ram_wr32(fuc, 0x1373ec, data);
- ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
- ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
-
- /* (re)program refpll, if required */
- if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
- (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
- ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
- ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
- ram_wr32(fuc, 0x137320, 0x00000000);
- ram_mask(fuc, 0x132030, 0xffff0000, runk0);
- ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
- ram_wr32(fuc, 0x132024, rcoef);
- ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
- ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
- ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
- ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
- }
-
- ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000010);
- ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000001);
- ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
-
- if (ram_have(fuc, gpioMV)) {
- u32 temp = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
- if (temp != ram_rd32(fuc, gpioMV)) {
- ram_wr32(fuc, gpiotrig, 1);
- ram_nsec(fuc, 64000);
- }
- }
-
- if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) ||
- (nv_ro08(bios, ramcfg + 0x07) & 0x10)) {
- ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
- ram_nsec(fuc, 20000);
- }
-
- if (ram->mode != 2) /*XXX*/ {
- if (nv_ro08(bios, ramcfg + 0x07) & 0x40)
- ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
- }
-
- data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2;
- ram_wr32(fuc, 0x10f65c, 0x00000011 * data);
- ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
- ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
-
- mask = 0x00010000;
- data = 0x00000000;
- if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80))
- data |= 0x03000000;
- if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40))
- data |= 0x00002000;
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10))
- data |= 0x00004000;
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08))
- data |= 0x00000003;
- else
- data |= 0x14000000;
- ram_mask(fuc, 0x10f824, mask, data);
- ram_nsec(fuc, 1000);
-
- if (nv_ro08(bios, ramcfg + 0x08) & 0x01)
- data = 0x00100000;
- else
- data = 0x00000000;
- ram_mask(fuc, 0x10f82c, 0x00100000, data);
-
- /* PFB timing */
- ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28));
- ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00));
- ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04));
- ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08));
- ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c));
- ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10));
- ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14));
- ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18));
- ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c));
- ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20));
- ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24));
-
- mask = 0x33f00000;
- data = 0x00000000;
- if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04))
- data |= 0x20200000;
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
- data |= 0x12800000;
- /*XXX: see note above about there probably being some condition
- * for the 10f824 stuff that uses ramcfg 3...
- */
- if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) {
- if (nv_ro08(bios, rammap + 0x08) & 0x0c) {
- if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
- mask |= 0x00000020;
- else
- data |= 0x00000020;
- mask |= 0x08000004;
- }
- data |= 0x04000000;
- } else {
- mask |= 0x44000020;
- data |= 0x08000004;
- }
-
- ram_mask(fuc, 0x10f808, mask, data);
-
- data = nv_ro08(bios, ramcfg + 0x03) & 0x0f;
- ram_wr32(fuc, 0x10f870, 0x11111111 * data);
-
- data = nv_ro16(bios, timing + 0x2c);
- ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4);
-
- if (((nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6) >
- ((nv_ro32(bios, timing + 0x28) & 0x7f000000) >> 24))
- data = (nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6;
- else
- data = (nv_ro32(bios, timing + 0x28) & 0x1f000000) >> 24;
- ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24);
-
- data = nv_ro08(bios, timing + 0x30);
- ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
-
- ram_wr32(fuc, 0x10f090, 0x4000007f);
- ram_nsec(fuc, 1000);
-
- ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
- ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
- ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
- ram_nsec(fuc, 1000);
-
- ram_nuke(fuc, mr[0]);
- ram_mask(fuc, mr[0], 0x100, 0x100);
- ram_mask(fuc, mr[0], 0x100, 0x000);
-
- ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]);
- ram_wr32(fuc, mr[0], ram->base.mr[0]);
- ram_nsec(fuc, 1000);
-
- ram_nuke(fuc, mr[0]);
- ram_mask(fuc, mr[0], 0x100, 0x100);
- ram_mask(fuc, mr[0], 0x100, 0x000);
-
- if (vc == 0 && ram_have(fuc, gpio2E)) {
- u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
- if (temp != ram_rd32(fuc, gpio2E)) {
- ram_wr32(fuc, gpiotrig, 1);
- ram_nsec(fuc, 20000);
- }
- }
-
- if (ram->mode != 2) {
- ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
- ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
- }
-
- ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
- ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
- ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
- ram_nsec(fuc, 1000);
-
- ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
-
- if (nv_ro08(bios, rammap + 0x08) & 0x01)
- data = 0x00000800;
- else
- data = 0x00000000;
- ram_mask(fuc, 0x10f200, 0x00000800, data);
- return 0;
-}
-
-/*******************************************************************************
- * main hooks
- ******************************************************************************/
-
-static int
-nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
-{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
- struct bit_entry M;
- int ret, refclk, strap, i;
- u32 data;
- u8 cnt;
-
- /* lookup memory config data relevant to the target frequency */
- ram->base.rammap.data = nvbios_rammap_match(bios, freq / 1000,
- &ram->base.rammap.version,
- &ram->base.rammap.size, &cnt,
- &ram->base.ramcfg.size);
- if (!ram->base.rammap.data || ram->base.rammap.version != 0x11 ||
- ram->base.rammap.size < 0x09) {
- nv_error(pfb, "invalid/missing rammap entry\n");
- return -EINVAL;
- }
-
- /* locate specific data set for the attached memory */
- if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) {
- nv_error(pfb, "invalid/missing memory table\n");
- return -EINVAL;
- }
-
- strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
- data = nv_ro16(bios, M.offset + 1);
- if (data)
- strap = nv_ro08(bios, data + strap);
-
- if (strap >= cnt) {
- nv_error(pfb, "invalid ramcfg strap\n");
- return -EINVAL;
- }
-
- ram->base.ramcfg.version = ram->base.rammap.version;
- ram->base.ramcfg.data = ram->base.rammap.data + ram->base.rammap.size +
- (ram->base.ramcfg.size * strap);
- if (!ram->base.ramcfg.data || ram->base.ramcfg.version != 0x11 ||
- ram->base.ramcfg.size < 0x08) {
- nv_error(pfb, "invalid/missing ramcfg entry\n");
- return -EINVAL;
- }
-
- /* lookup memory timings, if bios says they're present */
- strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00);
- if (strap != 0xff) {
- ram->base.timing.data =
- nvbios_timing_entry(bios, strap,
- &ram->base.timing.version,
- &ram->base.timing.size);
- if (!ram->base.timing.data ||
- ram->base.timing.version != 0x20 ||
- ram->base.timing.size < 0x33) {
- nv_error(pfb, "invalid/missing timing entry\n");
- return -EINVAL;
- }
- } else {
- ram->base.timing.data = 0;
- }
-
- ret = ram_init(fuc, pfb);
- if (ret)
- return ret;
-
- ram->mode = (freq > fuc->refpll.vco1.max_freq) ? 2 : 1;
- ram->from = ram_rd32(fuc, 0x1373f4) & 0x0000000f;
-
- /* XXX: this is *not* what nvidia do. on fermi nvidia generally
- * select, based on some unknown condition, one of the two possible
- * reference frequencies listed in the vbios table for mempll and
- * program refpll to that frequency.
- *
- * so far, i've seen very weird values being chosen by nvidia on
- * kepler boards, no idea how/why they're chosen.
- */
- refclk = freq;
- if (ram->mode == 2)
- refclk = fuc->mempll.refclk;
-
- /* calculate refpll coefficients */
- ret = nva3_pll_calc(nv_subdev(pfb), &fuc->refpll, refclk, &ram->N1,
- &ram->fN1, &ram->M1, &ram->P1);
- fuc->mempll.refclk = ret;
- if (ret <= 0) {
- nv_error(pfb, "unable to calc refpll\n");
- return -EINVAL;
- }
-
- /* calculate mempll coefficients, if we're using it */
- if (ram->mode == 2) {
- /* post-divider doesn't work... the reg takes the values but
- * appears to completely ignore it. there *is* a bit at
- * bit 28 that appears to divide the clock by 2 if set.
- */
- fuc->mempll.min_p = 1;
- fuc->mempll.max_p = 2;
-
- ret = nva3_pll_calc(nv_subdev(pfb), &fuc->mempll, freq,
- &ram->N2, NULL, &ram->M2, &ram->P2);
- if (ret <= 0) {
- nv_error(pfb, "unable to calc mempll\n");
- return -EINVAL;
- }
- }
-
- for (i = 0; i < ARRAY_SIZE(fuc->r_mr); i++) {
- if (ram_have(fuc, mr[i]))
- ram->base.mr[i] = ram_rd32(fuc, mr[i]);
- }
-
- switch (ram->base.type) {
- case NV_MEM_TYPE_DDR3:
- ret = nouveau_sddr3_calc(&ram->base);
- if (ret == 0)
- ret = nve0_ram_calc_sddr3(pfb, freq);
- break;
- case NV_MEM_TYPE_GDDR5:
- ret = nouveau_gddr5_calc(&ram->base);
- if (ret == 0)
- ret = nve0_ram_calc_gddr5(pfb, freq);
- break;
- default:
- ret = -ENOSYS;
- break;
- }
-
- return ret;
-}
-
-static int
-nve0_ram_prog(struct nouveau_fb *pfb)
-{
- struct nouveau_device *device = nv_device(pfb);
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
- ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
- return 0;
-}
-
-static void
-nve0_ram_tidy(struct nouveau_fb *pfb)
-{
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
- ram_exec(fuc, false);
-}
-
-static int
-nve0_ram_init(struct nouveau_object *object)
-{
- struct nouveau_fb *pfb = (void *)object->parent;
- struct nve0_ram *ram = (void *)object;
- struct nouveau_bios *bios = nouveau_bios(pfb);
- static const u8 train0[] = {
- 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
- };
- static const u32 train1[] = {
- 0x00000000, 0xffffffff,
- 0x55555555, 0xaaaaaaaa,
- 0x33333333, 0xcccccccc,
- 0xf0f0f0f0, 0x0f0f0f0f,
- 0x00ff00ff, 0xff00ff00,
- 0x0000ffff, 0xffff0000,
- };
- u8 ver, hdr, cnt, len, snr, ssz;
- u32 data, save;
- int ret, i;
-
- ret = nouveau_ram_init(&ram->base);
- if (ret)
- return ret;
-
- /* run a bunch of tables from rammap table. there's actually
- * individual pointers for each rammap entry too, but, nvidia
- * seem to just run the last two entries' scripts early on in
- * their init, and never again.. we'll just run 'em all once
- * for now.
- *
- * i strongly suspect that each script is for a separate mode
- * (likely selected by 0x10f65c's lower bits?), and the
- * binary driver skips the one that's already been setup by
- * the init tables.
- */
- data = nvbios_rammap_table(bios, &ver, &hdr, &cnt, &len, &snr, &ssz);
- if (!data || hdr < 0x15)
- return -EINVAL;
-
- cnt = nv_ro08(bios, data + 0x14); /* guess at count */
- data = nv_ro32(bios, data + 0x10); /* guess u32... */
- save = nv_rd32(pfb, 0x10f65c);
- for (i = 0; i < cnt; i++) {
- nv_mask(pfb, 0x10f65c, 0x000000f0, i << 4);
- nvbios_exec(&(struct nvbios_init) {
- .subdev = nv_subdev(pfb),
- .bios = bios,
- .offset = nv_ro32(bios, data), /* guess u32 */
- .execute = 1,
- });
- data += 4;
- }
- nv_wr32(pfb, 0x10f65c, save);
-
- switch (ram->base.type) {
- case NV_MEM_TYPE_GDDR5:
- for (i = 0; i < 0x30; i++) {
- nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8));
- nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]);
- nv_wr32(pfb, 0x10f918, train1[i % 12]);
- nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]);
- nv_wr32(pfb, 0x10f918, train1[i % 12]);
-
- nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8));
- nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]);
- nv_wr32(pfb, 0x10f91c, train1[i % 12]);
- nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]);
- nv_wr32(pfb, 0x10f91c, train1[i % 12]);
- }
-
- for (i = 0; i < 0x100; i++) {
- nv_wr32(pfb, 0x10f968, i);
- nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]);
- }
-
- for (i = 0; i < 0x100; i++) {
- nv_wr32(pfb, 0x10f96c, i);
- nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]);
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int
-nve0_ram_ctor(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_gpio *gpio = nouveau_gpio(pfb);
- struct dcb_gpio_func func;
- struct nve0_ram *ram;
- int ret;
-
- ret = nvc0_ram_create(parent, engine, oclass, &ram);
- *pobject = nv_object(ram);
- if (ret)
- return ret;
-
- switch (ram->base.type) {
- case NV_MEM_TYPE_DDR3:
- case NV_MEM_TYPE_GDDR5:
- ram->base.calc = nve0_ram_calc;
- ram->base.prog = nve0_ram_prog;
- ram->base.tidy = nve0_ram_tidy;
- break;
- default:
- nv_warn(pfb, "reclocking of this RAM type is unsupported\n");
- break;
- }
-
- // parse bios data for both pll's
- ret = nvbios_pll_parse(bios, 0x0c, &ram->fuc.refpll);
- if (ret) {
- nv_error(pfb, "mclk refpll data not found\n");
- return ret;
- }
-
- ret = nvbios_pll_parse(bios, 0x04, &ram->fuc.mempll);
- if (ret) {
- nv_error(pfb, "mclk pll data not found\n");
- return ret;
- }
-
- ret = gpio->find(gpio, 0, 0x18, DCB_GPIO_UNUSED, &func);
- if (ret == 0) {
- ram->fuc.r_gpioMV = ramfuc_reg(0x00d610 + (func.line * 0x04));
- ram->fuc.r_funcMV[0] = (func.log[0] ^ 2) << 12;
- ram->fuc.r_funcMV[1] = (func.log[1] ^ 2) << 12;
- }
-
- ret = gpio->find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
- if (ret == 0) {
- ram->fuc.r_gpio2E = ramfuc_reg(0x00d610 + (func.line * 0x04));
- ram->fuc.r_func2E[0] = (func.log[0] ^ 2) << 12;
- ram->fuc.r_func2E[1] = (func.log[1] ^ 2) << 12;
- }
-
- ram->fuc.r_gpiotrig = ramfuc_reg(0x00d604);
-
- ram->fuc.r_0x132020 = ramfuc_reg(0x132020);
- ram->fuc.r_0x132028 = ramfuc_reg(0x132028);
- ram->fuc.r_0x132024 = ramfuc_reg(0x132024);
- ram->fuc.r_0x132030 = ramfuc_reg(0x132030);
- ram->fuc.r_0x132034 = ramfuc_reg(0x132034);
- ram->fuc.r_0x132000 = ramfuc_reg(0x132000);
- ram->fuc.r_0x132004 = ramfuc_reg(0x132004);
- ram->fuc.r_0x132040 = ramfuc_reg(0x132040);
-
- ram->fuc.r_0x10f248 = ramfuc_reg(0x10f248);
- ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
- ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
- ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
- ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
- ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
- ram->fuc.r_0x10f2a4 = ramfuc_reg(0x10f2a4);
- ram->fuc.r_0x10f2a8 = ramfuc_reg(0x10f2a8);
- ram->fuc.r_0x10f2ac = ramfuc_reg(0x10f2ac);
- ram->fuc.r_0x10f2cc = ramfuc_reg(0x10f2cc);
- ram->fuc.r_0x10f2e8 = ramfuc_reg(0x10f2e8);
- ram->fuc.r_0x10f250 = ramfuc_reg(0x10f250);
- ram->fuc.r_0x10f24c = ramfuc_reg(0x10f24c);
- ram->fuc.r_0x10fec4 = ramfuc_reg(0x10fec4);
- ram->fuc.r_0x10fec8 = ramfuc_reg(0x10fec8);
- ram->fuc.r_0x10f604 = ramfuc_reg(0x10f604);
- ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614);
- ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610);
- ram->fuc.r_0x100770 = ramfuc_reg(0x100770);
- ram->fuc.r_0x100778 = ramfuc_reg(0x100778);
- ram->fuc.r_0x10f224 = ramfuc_reg(0x10f224);
-
- ram->fuc.r_0x10f870 = ramfuc_reg(0x10f870);
- ram->fuc.r_0x10f698 = ramfuc_reg(0x10f698);
- ram->fuc.r_0x10f694 = ramfuc_reg(0x10f694);
- ram->fuc.r_0x10f6b8 = ramfuc_reg(0x10f6b8);
- ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808);
- ram->fuc.r_0x10f670 = ramfuc_reg(0x10f670);
- ram->fuc.r_0x10f60c = ramfuc_reg(0x10f60c);
- ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830);
- ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec);
- ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800);
- ram->fuc.r_0x10f82c = ramfuc_reg(0x10f82c);
-
- ram->fuc.r_0x10f978 = ramfuc_reg(0x10f978);
- ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
- ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
-
- switch (ram->base.type) {
- case NV_MEM_TYPE_GDDR5:
- ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
- ram->fuc.r_mr[1] = ramfuc_reg(0x10f330);
- ram->fuc.r_mr[2] = ramfuc_reg(0x10f334);
- ram->fuc.r_mr[3] = ramfuc_reg(0x10f338);
- ram->fuc.r_mr[4] = ramfuc_reg(0x10f33c);
- ram->fuc.r_mr[5] = ramfuc_reg(0x10f340);
- ram->fuc.r_mr[6] = ramfuc_reg(0x10f344);
- ram->fuc.r_mr[7] = ramfuc_reg(0x10f348);
- ram->fuc.r_mr[8] = ramfuc_reg(0x10f354);
- ram->fuc.r_mr[15] = ramfuc_reg(0x10f34c);
- break;
- case NV_MEM_TYPE_DDR3:
- ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
- ram->fuc.r_mr[2] = ramfuc_reg(0x10f320);
- break;
- default:
- break;
- }
-
- ram->fuc.r_0x62c000 = ramfuc_reg(0x62c000);
- ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200);
- ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210);
- ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310);
- ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314);
- ram->fuc.r_0x10f318 = ramfuc_reg(0x10f318);
- ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090);
- ram->fuc.r_0x10f69c = ramfuc_reg(0x10f69c);
- ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824);
- ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0);
- ram->fuc.r_0x1373f4 = ramfuc_reg(0x1373f4);
- ram->fuc.r_0x137320 = ramfuc_reg(0x137320);
- ram->fuc.r_0x10f65c = ramfuc_reg(0x10f65c);
- ram->fuc.r_0x10f6bc = ramfuc_reg(0x10f6bc);
- ram->fuc.r_0x100710 = ramfuc_reg(0x100710);
- ram->fuc.r_0x10f750 = ramfuc_reg(0x10f750);
- return 0;
-}
-
-struct nouveau_oclass
-nve0_ram_oclass = {
- .handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = nve0_ram_init,
- .fini = _nouveau_ram_fini,
- }
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h
deleted file mode 100644
index 571077e..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __NVKM_FBRAM_SEQ_H__
-#define __NVKM_FBRAM_SEQ_H__
-
-#include <subdev/bus.h>
-#include <subdev/bus/hwsq.h>
-
-#define ram_init(s,p) hwsq_init(&(s)->base, (p))
-#define ram_exec(s,e) hwsq_exec(&(s)->base, (e))
-#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
-#define ram_rd32(s,r) hwsq_rd32(&(s)->base, &(s)->r_##r)
-#define ram_wr32(s,r,d) hwsq_wr32(&(s)->base, &(s)->r_##r, (d))
-#define ram_nuke(s,r) hwsq_nuke(&(s)->base, &(s)->r_##r)
-#define ram_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d))
-#define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
-#define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
-#define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n))
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
deleted file mode 100644
index ebd4cd9..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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 <bskeggs@redhat.com>
- */
-
-#include <subdev/bios.h>
-#include "priv.h"
-
-struct ramxlat {
- int id;
- u8 enc;
-};
-
-static inline int
-ramxlat(const struct ramxlat *xlat, int id)
-{
- while (xlat->id >= 0) {
- if (xlat->id == id)
- return xlat->enc;
- xlat++;
- }
- return -EINVAL;
-}
-
-static const struct ramxlat
-ramddr3_cl[] = {
- { 5, 2 }, { 6, 4 }, { 7, 6 }, { 8, 8 }, { 9, 10 }, { 10, 12 },
- { 11, 14 },
- /* the below are mentioned in some, but not all, ddr3 docs */
- { 12, 1 }, { 13, 3 }, { 14, 5 },
- { -1 }
-};
-
-static const struct ramxlat
-ramddr3_wr[] = {
- { 5, 1 }, { 6, 2 }, { 7, 3 }, { 8, 4 }, { 10, 5 }, { 12, 6 },
- /* the below are mentioned in some, but not all, ddr3 docs */
- { 14, 7 }, { 16, 0 },
- { -1 }
-};
-
-static const struct ramxlat
-ramddr3_cwl[] = {
- { 5, 0 }, { 6, 1 }, { 7, 2 }, { 8, 3 },
- /* the below are mentioned in some, but not all, ddr3 docs */
- { 9, 4 },
- { -1 }
-};
-
-int
-nouveau_sddr3_calc(struct nouveau_ram *ram)
-{
- struct nouveau_bios *bios = nouveau_bios(ram);
- int WL, CL, WR;
-
- switch (!!ram->timing.data * ram->timing.version) {
- case 0x20:
- WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
- CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
- WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
- break;
- default:
- return -ENOSYS;
- }
-
- WL = ramxlat(ramddr3_cwl, WL);
- CL = ramxlat(ramddr3_cl, CL);
- WR = ramxlat(ramddr3_wr, WR);
- if (WL < 0 || CL < 0 || WR < 0)
- return -EINVAL;
-
- ram->mr[0] &= ~0xe74;
- ram->mr[0] |= (WR & 0x07) << 9;
- ram->mr[0] |= (CL & 0x0e) << 3;
- ram->mr[0] |= (CL & 0x01) << 2;
-
- ram->mr[2] &= ~0x038;
- ram->mr[2] |= (WL & 0x07) << 3;
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
index f572c28..d422acc 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
@@ -67,7 +67,7 @@ nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line,
}
}
- return -ENOENT;
+ return -EINVAL;
}
static int
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
index 041fd5e..2895c19 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
@@ -195,7 +195,7 @@ nouveau_i2c_find_type(struct nouveau_i2c *i2c, u16 type)
static int
nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what,
- struct nouveau_i2c_board_info *info,
+ struct i2c_board_info *info,
bool (*match)(struct nouveau_i2c_port *,
struct i2c_board_info *))
{
@@ -208,29 +208,12 @@ nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what,
}
nv_debug(i2c, "probing %ss on bus: %d\n", what, port->index);
- for (i = 0; info[i].dev.addr; i++) {
- u8 orig_udelay = 0;
-
- if ((port->adapter.algo == &i2c_bit_algo) &&
- (info[i].udelay != 0)) {
- struct i2c_algo_bit_data *algo = port->adapter.algo_data;
- nv_debug(i2c, "using custom udelay %d instead of %d\n",
- info[i].udelay, algo->udelay);
- orig_udelay = algo->udelay;
- algo->udelay = info[i].udelay;
- }
-
- if (nv_probe_i2c(port, info[i].dev.addr) &&
- (!match || match(port, &info[i].dev))) {
- nv_info(i2c, "detected %s: %s\n", what,
- info[i].dev.type);
+ for (i = 0; info[i].addr; i++) {
+ if (nv_probe_i2c(port, info[i].addr) &&
+ (!match || match(port, &info[i]))) {
+ nv_info(i2c, "detected %s: %s\n", what, info[i].type);
return i;
}
-
- if (orig_udelay) {
- struct i2c_algo_bit_data *algo = port->adapter.algo_data;
- algo->udelay = orig_udelay;
- }
}
nv_debug(i2c, "no devices found.\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
index b4b9943..e290cfa 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
@@ -25,48 +25,38 @@
#include <subdev/mc.h>
#include <core/option.h>
-static inline u32
-nouveau_mc_intr_mask(struct nouveau_mc *pmc)
-{
- u32 intr = nv_rd32(pmc, 0x000100);
- if (intr == 0xffffffff) /* likely fallen off the bus */
- intr = 0x00000000;
- return intr;
-}
-
static irqreturn_t
nouveau_mc_intr(int irq, void *arg)
{
struct nouveau_mc *pmc = arg;
- const struct nouveau_mc_oclass *oclass = (void *)nv_object(pmc)->oclass;
- const struct nouveau_mc_intr *map = oclass->intr;
+ const struct nouveau_mc_intr *map = pmc->intr_map;
+ struct nouveau_device *device = nv_device(pmc);
struct nouveau_subdev *unit;
- u32 intr;
+ u32 stat, intr;
+
+ intr = stat = nv_rd32(pmc, 0x000100);
+ if (intr == 0xffffffff)
+ return IRQ_NONE;
+ while (stat && map->stat) {
+ if (stat & map->stat) {
+ unit = nouveau_subdev(pmc, map->unit);
+ if (unit && unit->intr)
+ unit->intr(unit);
+ intr &= ~map->stat;
+ }
+ map++;
+ }
- nv_wr32(pmc, 0x000140, 0x00000000);
- nv_rd32(pmc, 0x000140);
- intr = nouveau_mc_intr_mask(pmc);
if (pmc->use_msi)
- oclass->msi_rearm(pmc);
+ nv_wr08(pmc->base.base.parent, 0x00088068, 0xff);
if (intr) {
- u32 stat = intr = nouveau_mc_intr_mask(pmc);
- while (map->stat) {
- if (intr & map->stat) {
- unit = nouveau_subdev(pmc, map->unit);
- if (unit && unit->intr)
- unit->intr(unit);
- stat &= ~map->stat;
- }
- map++;
- }
-
- if (stat)
- nv_error(pmc, "unknown intr 0x%08x\n", stat);
+ nv_error(pmc, "unknown intr 0x%08x\n", stat);
}
- nv_wr32(pmc, 0x000140, 0x00000001);
- return intr ? IRQ_HANDLED : IRQ_NONE;
+ if (stat == IRQ_HANDLED)
+ pm_runtime_mark_last_busy(&device->pdev->dev);
+ return stat ? IRQ_HANDLED : IRQ_NONE;
}
int
@@ -101,42 +91,37 @@ _nouveau_mc_dtor(struct nouveau_object *object)
int
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *bclass, int length, void **pobject)
+ struct nouveau_oclass *oclass,
+ const struct nouveau_mc_intr *intr_map,
+ int length, void **pobject)
{
- const struct nouveau_mc_oclass *oclass = (void *)bclass;
struct nouveau_device *device = nv_device(parent);
struct nouveau_mc *pmc;
int ret;
- ret = nouveau_subdev_create_(parent, engine, bclass, 0, "PMC",
+ ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMC",
"master", length, pobject);
pmc = *pobject;
if (ret)
return ret;
+ pmc->intr_map = intr_map;
+
switch (device->pdev->device & 0x0ff0) {
- case 0x00f0:
- case 0x02e0:
- /* BR02? NFI how these would be handled yet exactly */
+ case 0x00f0: /* BR02? */
+ case 0x02e0: /* BR02? */
+ pmc->use_msi = false;
break;
default:
- switch (device->chipset) {
- case 0xaa: break; /* reported broken, nv also disable it */
- default:
- pmc->use_msi = true;
- break;
- }
- }
-
- pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", pmc->use_msi);
- if (pmc->use_msi && oclass->msi_rearm) {
- pmc->use_msi = pci_enable_msi(device->pdev) == 0;
+ pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", false);
if (pmc->use_msi) {
- nv_info(pmc, "MSI interrupts enabled\n");
- oclass->msi_rearm(pmc);
+ pmc->use_msi = pci_enable_msi(device->pdev) == 0;
+ if (pmc->use_msi) {
+ nv_info(pmc, "MSI interrupts enabled\n");
+ nv_wr08(device, 0x00088068, 0xff);
+ }
}
- } else {
- pmc->use_msi = false;
+ break;
}
ret = request_irq(device->pdev->irq, nouveau_mc_intr,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
index 2d787e4..64aa4ed 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
@@ -22,14 +22,17 @@
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/mc.h>
+
+struct nv04_mc_priv {
+ struct nouveau_mc base;
+};
const struct nouveau_mc_intr
nv04_mc_intr[] = {
{ 0x00000001, NVDEV_ENGINE_MPEG }, /* NV17- MPEG/ME */
{ 0x00000100, NVDEV_ENGINE_FIFO },
{ 0x00001000, NVDEV_ENGINE_GR },
- { 0x00010000, NVDEV_ENGINE_DISP },
{ 0x00020000, NVDEV_ENGINE_VP }, /* NV40- */
{ 0x00100000, NVDEV_SUBDEV_TIMER },
{ 0x01000000, NVDEV_ENGINE_DISP }, /* NV04- PCRTC0 */
@@ -39,18 +42,7 @@ nv04_mc_intr[] = {
{}
};
-int
-nv04_mc_init(struct nouveau_object *object)
-{
- struct nv04_mc_priv *priv = (void *)object;
-
- nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
- nv_wr32(priv, 0x001850, 0x00000001); /* disable rom access */
-
- return nouveau_mc_init(&priv->base);
-}
-
-int
+static int
nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
@@ -58,7 +50,7 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_mc_priv *priv;
int ret;
- ret = nouveau_mc_create(parent, engine, oclass, &priv);
+ ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -66,14 +58,24 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv04_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+int
+nv04_mc_init(struct nouveau_object *object)
+{
+ struct nv04_mc_priv *priv = (void *)object;
+
+ nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
+ nv_wr32(priv, 0x001850, 0x00000001); /* disable rom access */
+
+ return nouveau_mc_init(&priv->base);
+}
+
+struct nouveau_oclass
+nv04_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_mc_ctor,
.dtor = _nouveau_mc_dtor,
.init = nv04_mc_init,
.fini = _nouveau_mc_fini,
},
- .intr = nv04_mc_intr,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h
deleted file mode 100644
index b0d5c31..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __NVKM_MC_NV04_H__
-#define __NVKM_MC_NV04_H__
-
-#include <subdev/mc.h>
-
-struct nv04_mc_priv {
- struct nouveau_mc base;
-};
-
-int nv04_mc_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-extern const struct nouveau_mc_intr nv04_mc_intr[];
-int nv04_mc_init(struct nouveau_object *);
-void nv40_mc_msi_rearm(struct nouveau_mc *);
-int nv50_mc_init(struct nouveau_object *);
-extern const struct nouveau_mc_intr nv50_mc_intr[];
-extern const struct nouveau_mc_intr nvc0_mc_intr[];
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c
deleted file mode 100644
index 5b1faec..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 "nv04.h"
-
-void
-nv40_mc_msi_rearm(struct nouveau_mc *pmc)
-{
- struct nv04_mc_priv *priv = (void *)pmc;
- nv_wr08(priv, 0x088068, 0xff);
-}
-
-struct nouveau_oclass *
-nv40_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x40),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
- .init = nv04_mc_init,
- .fini = _nouveau_mc_fini,
- },
- .intr = nv04_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
index 3bfee5c..d989178 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
@@ -22,12 +22,32 @@
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/mc.h>
+
+struct nv44_mc_priv {
+ struct nouveau_mc base;
+};
+
+static int
+nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv44_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
static int
nv44_mc_init(struct nouveau_object *object)
{
- struct nv04_mc_priv *priv = (void *)object;
+ struct nv44_mc_priv *priv = (void *)object;
u32 tmp = nv_rd32(priv, 0x10020c);
nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
@@ -40,15 +60,13 @@ nv44_mc_init(struct nouveau_object *object)
return nouveau_mc_init(&priv->base);
}
-struct nouveau_oclass *
-nv44_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x44),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_mc_ctor,
+struct nouveau_oclass
+nv44_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x44),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv44_mc_ctor,
.dtor = _nouveau_mc_dtor,
.init = nv44_mc_init,
.fini = _nouveau_mc_fini,
},
- .intr = nv04_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
index e8822a9..2b1afe2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
@@ -22,9 +22,13 @@
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/mc.h>
-const struct nouveau_mc_intr
+struct nv50_mc_priv {
+ struct nouveau_mc base;
+};
+
+static const struct nouveau_mc_intr
nv50_mc_intr[] = {
{ 0x00000001, NVDEV_ENGINE_MPEG },
{ 0x00000100, NVDEV_ENGINE_FIFO },
@@ -41,30 +45,37 @@ nv50_mc_intr[] = {
{},
};
-static void
-nv50_mc_msi_rearm(struct nouveau_mc *pmc)
+static int
+nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
{
- struct nouveau_device *device = nv_device(pmc);
- pci_write_config_byte(device->pdev, 0x68, 0xff);
+ struct nv50_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, nv50_mc_intr, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
}
int
nv50_mc_init(struct nouveau_object *object)
{
- struct nv04_mc_priv *priv = (void *)object;
+ struct nv50_mc_priv *priv = (void *)object;
nv_wr32(priv, 0x000200, 0xffffffff); /* everything on */
return nouveau_mc_init(&priv->base);
}
-struct nouveau_oclass *
-nv50_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_mc_ctor,
+struct nouveau_oclass
+nv50_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_mc_ctor,
.dtor = _nouveau_mc_dtor,
.init = nv50_mc_init,
.fini = _nouveau_mc_fini,
},
- .intr = nv50_mc_intr,
- .msi_rearm = nv50_mc_msi_rearm,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c
deleted file mode 100644
index 5f45411..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 "nv04.h"
-
-struct nouveau_oclass *
-nv94_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x94),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
- },
- .intr = nv50_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
index f8a6f18..0671041 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
@@ -22,7 +22,11 @@
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/mc.h>
+
+struct nv98_mc_priv {
+ struct nouveau_mc base;
+};
static const struct nouveau_mc_intr
nv98_mc_intr[] = {
@@ -32,7 +36,6 @@ nv98_mc_intr[] = {
{ 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84:NVA3 */
{ 0x00008000, NVDEV_ENGINE_BSP },
{ 0x00020000, NVDEV_ENGINE_VP },
- { 0x00040000, NVDEV_SUBDEV_PWR }, /* NVA3:NVC0 */
{ 0x00080000, NVDEV_SUBDEV_THERM }, /* NVA3:NVC0 */
{ 0x00100000, NVDEV_SUBDEV_TIMER },
{ 0x00200000, NVDEV_SUBDEV_GPIO },
@@ -44,15 +47,29 @@ nv98_mc_intr[] = {
{},
};
-struct nouveau_oclass *
-nv98_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x98),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_mc_ctor,
+static int
+nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, nv98_mc_intr, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+struct nouveau_oclass
+nv98_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_mc_ctor,
.dtor = _nouveau_mc_dtor,
.init = nv50_mc_init,
.fini = _nouveau_mc_fini,
},
- .intr = nv98_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
index c02b476..104175c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
@@ -22,9 +22,13 @@
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include <subdev/mc.h>
-const struct nouveau_mc_intr
+struct nvc0_mc_priv {
+ struct nouveau_mc base;
+};
+
+static const struct nouveau_mc_intr
nvc0_mc_intr[] = {
{ 0x00000001, NVDEV_ENGINE_PPP },
{ 0x00000020, NVDEV_ENGINE_COPY0 },
@@ -37,7 +41,6 @@ nvc0_mc_intr[] = {
{ 0x00020000, NVDEV_ENGINE_VP },
{ 0x00100000, NVDEV_SUBDEV_TIMER },
{ 0x00200000, NVDEV_SUBDEV_GPIO },
- { 0x01000000, NVDEV_SUBDEV_PWR },
{ 0x02000000, NVDEV_SUBDEV_LTCG },
{ 0x04000000, NVDEV_ENGINE_DISP },
{ 0x10000000, NVDEV_SUBDEV_BUS },
@@ -46,22 +49,29 @@ nvc0_mc_intr[] = {
{},
};
-static void
-nvc0_mc_msi_rearm(struct nouveau_mc *pmc)
+static int
+nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
{
- struct nv04_mc_priv *priv = (void *)pmc;
- nv_wr32(priv, 0x088704, 0x00000000);
+ struct nvc0_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, nvc0_mc_intr, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
}
-struct nouveau_oclass *
-nvc0_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_mc_ctor,
+struct nouveau_oclass
+nvc0_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_mc_ctor,
.dtor = _nouveau_mc_dtor,
.init = nv50_mc_init,
.fini = _nouveau_mc_fini,
},
- .intr = nvc0_mc_intr,
- .msi_rearm = nvc0_mc_msi_rearm,
-}.base;
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c
deleted file mode 100644
index 837e545..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 "nv04.h"
-
-struct nouveau_oclass *
-nvc3_mc_oclass = &(struct nouveau_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0xc3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
- },
- .intr = nvc0_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
index 1291204..e286e13 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
@@ -116,7 +116,7 @@ mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version)
acpi_handle handle;
int ret;
- handle = ACPI_HANDLE(&device->pdev->dev);
+ handle = DEVICE_ACPI_HANDLE(&device->pdev->dev);
if (!handle)
return false;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c
deleted file mode 100644
index d4fd3bc9..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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/pwr.h>
-#include <subdev/timer.h>
-
-static int
-nouveau_pwr_send(struct nouveau_pwr *ppwr, u32 reply[2],
- u32 process, u32 message, u32 data0, u32 data1)
-{
- struct nouveau_subdev *subdev = nv_subdev(ppwr);
- u32 addr;
-
- /* wait for a free slot in the fifo */
- addr = nv_rd32(ppwr, 0x10a4a0);
- if (!nv_wait_ne(ppwr, 0x10a4b0, 0xffffffff, addr ^ 8))
- return -EBUSY;
-
- /* we currently only support a single process at a time waiting
- * on a synchronous reply, take the PPWR mutex and tell the
- * receive handler what we're waiting for
- */
- if (reply) {
- mutex_lock(&subdev->mutex);
- ppwr->recv.message = message;
- ppwr->recv.process = process;
- }
-
- /* acquire data segment access */
- do {
- nv_wr32(ppwr, 0x10a580, 0x00000001);
- } while (nv_rd32(ppwr, 0x10a580) != 0x00000001);
-
- /* write the packet */
- nv_wr32(ppwr, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) +
- ppwr->send.base));
- nv_wr32(ppwr, 0x10a1c4, process);
- nv_wr32(ppwr, 0x10a1c4, message);
- nv_wr32(ppwr, 0x10a1c4, data0);
- nv_wr32(ppwr, 0x10a1c4, data1);
- nv_wr32(ppwr, 0x10a4a0, (addr + 1) & 0x0f);
-
- /* release data segment access */
- nv_wr32(ppwr, 0x10a580, 0x00000000);
-
- /* wait for reply, if requested */
- if (reply) {
- wait_event(ppwr->recv.wait, (ppwr->recv.process == 0));
- reply[0] = ppwr->recv.data[0];
- reply[1] = ppwr->recv.data[1];
- mutex_unlock(&subdev->mutex);
- }
-
- return 0;
-}
-
-static void
-nouveau_pwr_recv(struct work_struct *work)
-{
- struct nouveau_pwr *ppwr =
- container_of(work, struct nouveau_pwr, recv.work);
- u32 process, message, data0, data1;
-
- /* nothing to do if GET == PUT */
- u32 addr = nv_rd32(ppwr, 0x10a4cc);
- if (addr == nv_rd32(ppwr, 0x10a4c8))
- return;
-
- /* acquire data segment access */
- do {
- nv_wr32(ppwr, 0x10a580, 0x00000002);
- } while (nv_rd32(ppwr, 0x10a580) != 0x00000002);
-
- /* read the packet */
- nv_wr32(ppwr, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) +
- ppwr->recv.base));
- process = nv_rd32(ppwr, 0x10a1c4);
- message = nv_rd32(ppwr, 0x10a1c4);
- data0 = nv_rd32(ppwr, 0x10a1c4);
- data1 = nv_rd32(ppwr, 0x10a1c4);
- nv_wr32(ppwr, 0x10a4cc, (addr + 1) & 0x0f);
-
- /* release data segment access */
- nv_wr32(ppwr, 0x10a580, 0x00000000);
-
- /* wake process if it's waiting on a synchronous reply */
- if (ppwr->recv.process) {
- if (process == ppwr->recv.process &&
- message == ppwr->recv.message) {
- ppwr->recv.data[0] = data0;
- ppwr->recv.data[1] = data1;
- ppwr->recv.process = 0;
- wake_up(&ppwr->recv.wait);
- return;
- }
- }
-
- /* right now there's no other expected responses from the engine,
- * so assume that any unexpected message is an error.
- */
- nv_warn(ppwr, "%c%c%c%c 0x%08x 0x%08x 0x%08x 0x%08x\n",
- (char)((process & 0x000000ff) >> 0),
- (char)((process & 0x0000ff00) >> 8),
- (char)((process & 0x00ff0000) >> 16),
- (char)((process & 0xff000000) >> 24),
- process, message, data0, data1);
-}
-
-static void
-nouveau_pwr_intr(struct nouveau_subdev *subdev)
-{
- struct nouveau_pwr *ppwr = (void *)subdev;
- u32 disp = nv_rd32(ppwr, 0x10a01c);
- u32 intr = nv_rd32(ppwr, 0x10a008) & disp & ~(disp >> 16);
-
- if (intr & 0x00000020) {
- u32 stat = nv_rd32(ppwr, 0x10a16c);
- if (stat & 0x80000000) {
- nv_error(ppwr, "UAS fault at 0x%06x addr 0x%08x\n",
- stat & 0x00ffffff, nv_rd32(ppwr, 0x10a168));
- nv_wr32(ppwr, 0x10a16c, 0x00000000);
- intr &= ~0x00000020;
- }
- }
-
- if (intr & 0x00000040) {
- schedule_work(&ppwr->recv.work);
- nv_wr32(ppwr, 0x10a004, 0x00000040);
- intr &= ~0x00000040;
- }
-
- if (intr & 0x00000080) {
- nv_info(ppwr, "wr32 0x%06x 0x%08x\n", nv_rd32(ppwr, 0x10a7a0),
- nv_rd32(ppwr, 0x10a7a4));
- nv_wr32(ppwr, 0x10a004, 0x00000080);
- intr &= ~0x00000080;
- }
-
- if (intr) {
- nv_error(ppwr, "intr 0x%08x\n", intr);
- nv_wr32(ppwr, 0x10a004, intr);
- }
-}
-
-int
-_nouveau_pwr_fini(struct nouveau_object *object, bool suspend)
-{
- struct nouveau_pwr *ppwr = (void *)object;
-
- nv_wr32(ppwr, 0x10a014, 0x00000060);
- flush_work(&ppwr->recv.work);
-
- return nouveau_subdev_fini(&ppwr->base, suspend);
-}
-
-int
-_nouveau_pwr_init(struct nouveau_object *object)
-{
- struct nouveau_pwr *ppwr = (void *)object;
- int ret, i;
-
- ret = nouveau_subdev_init(&ppwr->base);
- if (ret)
- return ret;
-
- nv_subdev(ppwr)->intr = nouveau_pwr_intr;
- ppwr->message = nouveau_pwr_send;
-
- /* prevent previous ucode from running, wait for idle, reset */
- nv_wr32(ppwr, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */
- nv_wait(ppwr, 0x10a04c, 0xffffffff, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x00002000, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x00002000, 0x00002000);
-
- /* upload data segment */
- nv_wr32(ppwr, 0x10a1c0, 0x01000000);
- for (i = 0; i < ppwr->data.size / 4; i++)
- nv_wr32(ppwr, 0x10a1c4, ppwr->data.data[i]);
-
- /* upload code segment */
- nv_wr32(ppwr, 0x10a180, 0x01000000);
- for (i = 0; i < ppwr->code.size / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(ppwr, 0x10a188, i >> 6);
- nv_wr32(ppwr, 0x10a184, ppwr->code.data[i]);
- }
-
- /* start it running */
- nv_wr32(ppwr, 0x10a10c, 0x00000000);
- nv_wr32(ppwr, 0x10a104, 0x00000000);
- nv_wr32(ppwr, 0x10a100, 0x00000002);
-
- /* wait for valid host->pwr ring configuration */
- if (!nv_wait_ne(ppwr, 0x10a4d0, 0xffffffff, 0x00000000))
- return -EBUSY;
- ppwr->send.base = nv_rd32(ppwr, 0x10a4d0) & 0x0000ffff;
- ppwr->send.size = nv_rd32(ppwr, 0x10a4d0) >> 16;
-
- /* wait for valid pwr->host ring configuration */
- if (!nv_wait_ne(ppwr, 0x10a4dc, 0xffffffff, 0x00000000))
- return -EBUSY;
- ppwr->recv.base = nv_rd32(ppwr, 0x10a4dc) & 0x0000ffff;
- ppwr->recv.size = nv_rd32(ppwr, 0x10a4dc) >> 16;
-
- nv_wr32(ppwr, 0x10a010, 0x000000e0);
- return 0;
-}
-
-int
-nouveau_pwr_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
-{
- struct nouveau_pwr *ppwr;
- int ret;
-
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PPWR",
- "pwr", length, pobject);
- ppwr = *pobject;
- if (ret)
- return ret;
-
- INIT_WORK(&ppwr->recv.work, nouveau_pwr_recv);
- init_waitqueue_head(&ppwr->recv.wait);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc
deleted file mode 100644
index 2284ecb..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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
- */
-
-#ifdef INCLUDE_PROC
-process(PROC_HOST, #host_init, #host_recv)
-#endif
-
-/******************************************************************************
- * HOST data segment
- *****************************************************************************/
-#ifdef INCLUDE_DATA
-// HOST (R)FIFO packet format
-.equ #fifo_process 0x00
-.equ #fifo_message 0x04
-.equ #fifo_data0 0x08
-.equ #fifo_data1 0x0c
-
-// HOST HOST->PWR queue description
-.equ #fifo_qlen 4 // log2(size of queue entry in bytes)
-.equ #fifo_qnum 3 // log2(max number of entries in queue)
-.equ #fifo_qmaskb (1 << #fifo_qnum) // max number of entries in queue
-.equ #fifo_qmaskp (#fifo_qmaskb - 1)
-.equ #fifo_qmaskf ((#fifo_qmaskb << 1) - 1)
-.equ #fifo_qsize (1 << (#fifo_qlen + #fifo_qnum))
-fifo_queue: .skip 128 // #fifo_qsize
-
-// HOST PWR->HOST queue description
-.equ #rfifo_qlen 4 // log2(size of queue entry in bytes)
-.equ #rfifo_qnum 3 // log2(max number of entries in queue)
-.equ #rfifo_qmaskb (1 << #rfifo_qnum) // max number of entries in queue
-.equ #rfifo_qmaskp (#rfifo_qmaskb - 1)
-.equ #rfifo_qmaskf ((#rfifo_qmaskb << 1) - 1)
-.equ #rfifo_qsize (1 << (#rfifo_qlen + #rfifo_qnum))
-rfifo_queue: .skip 128 // #rfifo_qsize
-#endif
-
-/******************************************************************************
- * HOST code segment
- *****************************************************************************/
-#ifdef INCLUDE_CODE
-// HOST->PWR comms - dequeue message(s) for process(es) from FIFO
-//
-// $r15 - current (host)
-// $r0 - zero
-host_send:
- nv_iord($r1, NV_PPWR_FIFO_GET(0))
- nv_iord($r2, NV_PPWR_FIFO_PUT(0))
- cmp b32 $r1 $r2
- bra e #host_send_done
- // calculate address of message
- and $r14 $r1 #fifo_qmaskp
- shl b32 $r14 $r14 #fifo_qlen
- add b32 $r14 #fifo_queue
-
- // read message data, and pass to appropriate process
- ld b32 $r11 D[$r14 + #fifo_data1]
- ld b32 $r12 D[$r14 + #fifo_data0]
- ld b32 $r13 D[$r14 + #fifo_message]
- ld b32 $r14 D[$r14 + #fifo_process]
- call(send)
-
- // increment GET
- add b32 $r1 0x1
- and $r14 $r1 #fifo_qmaskf
- nv_iowr(NV_PPWR_FIFO_GET(0), $r1)
- bra #host_send
- host_send_done:
- ret
-
-// PWR->HOST comms - enqueue message for HOST to RFIFO
-//
-// $r15 - current (host)
-// $r14 - process
-// $r13 - message
-// $r12 - message data 0
-// $r11 - message data 1
-// $r0 - zero
-host_recv:
- // message from intr handler == HOST->PWR comms pending
- mov $r1 (PROC_KERN & 0x0000ffff)
- sethi $r1 (PROC_KERN & 0xffff0000)
- cmp b32 $r14 $r1
- bra e #host_send
-
- // wait for space in RFIFO
- host_recv_wait:
- nv_iord($r1, NV_PPWR_RFIFO_GET)
- nv_iord($r2, NV_PPWR_RFIFO_PUT)
- xor $r1 #rfifo_qmaskb
- cmp b32 $r1 $r2
- bra e #host_recv_wait
-
- and $r3 $r2 #rfifo_qmaskp
- shl b32 $r3 #rfifo_qlen
- add b32 $r3 #rfifo_queue
-
- // enqueue message
- st b32 D[$r3 + #fifo_data1] $r11
- st b32 D[$r3 + #fifo_data0] $r12
- st b32 D[$r3 + #fifo_message] $r13
- st b32 D[$r3 + #fifo_process] $r14
-
- add b32 $r2 0x1
- and $r2 #rfifo_qmaskf
- nv_iowr(NV_PPWR_RFIFO_PUT, $r2)
-
- // notify host of pending message
- mov $r2 NV_PPWR_INTR_TRIGGER_USER0
- nv_iowr(NV_PPWR_INTR_TRIGGER, $r2)
- ret
-
-// $r15 - current (host)
-// $r0 - zero
-host_init:
- // store each fifo's base/size in H2D/D2H scratch regs
- mov $r1 #fifo_qsize
- shl b32 $r1 16
- or $r1 #fifo_queue
- nv_iowr(NV_PPWR_H2D, $r1);
-
- mov $r1 #rfifo_qsize
- shl b32 $r1 16
- or $r1 #rfifo_queue
- nv_iowr(NV_PPWR_D2H, $r1);
-
- // enable fifo subintr for first fifo
- mov $r1 1
- nv_iowr(NV_PPWR_FIFO_INTR_EN, $r1)
- ret
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc
deleted file mode 100644
index 98f1c37..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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
- */
-
-#ifdef INCLUDE_PROC
-process(PROC_IDLE, #idle, #idle_recv)
-#endif
-
-/******************************************************************************
- * IDLE data segment
- *****************************************************************************/
-#ifdef INCLUDE_DATA
-#endif
-
-/******************************************************************************
- * IDLE code segment
- *****************************************************************************/
-#ifdef INCLUDE_CODE
-// description
-//
-// $r15 - current (idle)
-// $r14 - message
-// $r0 - zero
-idle_recv:
- ret
-
-// description
-//
-// $r15 - current (idle)
-// $r0 - zero
-idle:
- // set our "no interrupt has occurred during our execution" flag
- bset $flags $p0
-
- // count IDLE invocations for debugging purposes
- nv_iord($r1, NV_PPWR_DSCRATCH(1))
- add b32 $r1 1
- nv_iowr(NV_PPWR_DSCRATCH(1), $r1)
-
- // keep looping while there's pending messages for any process
- idle_loop:
- mov $r1 #proc_list_head
- bclr $flags $p2
- idle_proc:
- // process the process' messages until there's none left
- idle_proc_exec:
- push $r1
- mov b32 $r14 $r1
- call(recv)
- pop $r1
- bra not $p1 #idle_proc_next
- bset $flags $p2
- bra #idle_proc_exec
- // next process!
- idle_proc_next:
- add b32 $r1 #proc_size
- cmp b32 $r1 $r15
- bra ne #idle_proc
- bra $p2 #idle_loop
-
- // sleep if no interrupts have occurred
- sleep $p0
- bra #idle
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc
deleted file mode 100644
index 0a7b05f..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * 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
- */
-
-/******************************************************************************
- * kernel data segment
- *****************************************************************************/
-#ifdef INCLUDE_PROC
-proc_kern:
-process(PROC_KERN, 0, 0)
-proc_list_head:
-#endif
-
-#ifdef INCLUDE_DATA
-proc_list_tail:
-time_prev: .b32 0
-time_next: .b32 0
-#endif
-
-/******************************************************************************
- * kernel code segment
- *****************************************************************************/
-#ifdef INCLUDE_CODE
- bra #init
-
-// read nv register
-//
-// $r15 - current
-// $r14 - addr
-// $r13 - data (return)
-// $r0 - zero
-rd32:
- nv_iowr(NV_PPWR_MMIO_ADDR, $r14)
- mov $r14 NV_PPWR_MMIO_CTRL_OP_RD
- sethi $r14 NV_PPWR_MMIO_CTRL_TRIGGER
- nv_iowr(NV_PPWR_MMIO_CTRL, $r14)
- rd32_wait:
- nv_iord($r14, NV_PPWR_MMIO_CTRL)
- and $r14 NV_PPWR_MMIO_CTRL_STATUS
- bra nz #rd32_wait
- nv_iord($r13, NV_PPWR_MMIO_DATA)
- ret
-
-// write nv register
-//
-// $r15 - current
-// $r14 - addr
-// $r13 - data
-// $r0 - zero
-wr32:
- nv_iowr(NV_PPWR_MMIO_ADDR, $r14)
- nv_iowr(NV_PPWR_MMIO_DATA, $r13)
- mov $r14 NV_PPWR_MMIO_CTRL_OP_WR
- or $r14 NV_PPWR_MMIO_CTRL_MASK_B32_0
- sethi $r14 NV_PPWR_MMIO_CTRL_TRIGGER
-
-#ifdef NVKM_FALCON_MMIO_TRAP
- mov $r8 NV_PPWR_INTR_TRIGGER_USER1
- nv_iowr(NV_PPWR_INTR_TRIGGER, $r8)
- wr32_host:
- nv_iord($r8, NV_PPWR_INTR)
- and $r8 NV_PPWR_INTR_USER1
- bra nz #wr32_host
-#endif
-
- nv_iowr(NV_PPWR_MMIO_CTRL, $r14)
- wr32_wait:
- nv_iord($r14, NV_PPWR_MMIO_CTRL)
- and $r14 NV_PPWR_MMIO_CTRL_STATUS
- bra nz #wr32_wait
- ret
-
-// busy-wait for a period of time
-//
-// $r15 - current
-// $r14 - ns
-// $r0 - zero
-nsec:
- nv_iord($r8, NV_PPWR_TIMER_LOW)
- nsec_loop:
- nv_iord($r9, NV_PPWR_TIMER_LOW)
- sub b32 $r9 $r8
- cmp b32 $r9 $r14
- bra l #nsec_loop
- ret
-
-// busy-wait for a period of time
-//
-// $r15 - current
-// $r14 - addr
-// $r13 - mask
-// $r12 - data
-// $r11 - timeout (ns)
-// $r0 - zero
-wait:
- nv_iord($r8, NV_PPWR_TIMER_LOW)
- wait_loop:
- nv_rd32($r10, $r14)
- and $r10 $r13
- cmp b32 $r10 $r12
- bra e #wait_done
- nv_iord($r9, NV_PPWR_TIMER_LOW)
- sub b32 $r9 $r8
- cmp b32 $r9 $r11
- bra l #wait_loop
- wait_done:
- ret
-
-// $r15 - current (kern)
-// $r14 - process
-// $r8 - NV_PPWR_INTR
-intr_watchdog:
- // read process' timer status, skip if not enabled
- ld b32 $r9 D[$r14 + #proc_time]
- cmp b32 $r9 0
- bra z #intr_watchdog_next_proc
-
- // subtract last timer's value from process' timer,
- // if it's <= 0 then the timer has expired
- ld b32 $r10 D[$r0 + #time_prev]
- sub b32 $r9 $r10
- bra g #intr_watchdog_next_time
- mov $r13 KMSG_ALARM
- call(send_proc)
- clear b32 $r9
- bra #intr_watchdog_next_proc
-
- // otherwise, update the next timer's value if this
- // process' timer is the soonest
- intr_watchdog_next_time:
- // ... or if there's no next timer yet
- ld b32 $r10 D[$r0 + #time_next]
- cmp b32 $r10 0
- bra z #intr_watchdog_next_time_set
-
- cmp b32 $r9 $r10
- bra g #intr_watchdog_next_proc
- intr_watchdog_next_time_set:
- st b32 D[$r0 + #time_next] $r9
-
- // update process' timer status, and advance
- intr_watchdog_next_proc:
- st b32 D[$r14 + #proc_time] $r9
- add b32 $r14 #proc_size
- cmp b32 $r14 #proc_list_tail
- bra ne #intr_watchdog
- ret
-
-intr:
- push $r0
- clear b32 $r0
- push $r8
- push $r9
- push $r10
- push $r11
- push $r12
- push $r13
- push $r14
- push $r15
- mov $r15 #proc_kern
- mov $r8 $flags
- push $r8
-
- nv_iord($r8, NV_PPWR_DSCRATCH(0))
- add b32 $r8 1
- nv_iowr(NV_PPWR_DSCRATCH(0), $r8)
-
- nv_iord($r8, NV_PPWR_INTR)
- and $r9 $r8 NV_PPWR_INTR_WATCHDOG
- bra z #intr_skip_watchdog
- st b32 D[$r0 + #time_next] $r0
- mov $r14 #proc_list_head
- call(intr_watchdog)
- ld b32 $r9 D[$r0 + #time_next]
- cmp b32 $r9 0
- bra z #intr_skip_watchdog
- nv_iowr(NV_PPWR_WATCHDOG_TIME, $r9)
- st b32 D[$r0 + #time_prev] $r9
-
- intr_skip_watchdog:
- and $r9 $r8 NV_PPWR_INTR_SUBINTR
- bra z #intr_skip_subintr
- nv_iord($r9, NV_PPWR_SUBINTR)
- and $r10 $r9 NV_PPWR_SUBINTR_FIFO
- bra z #intr_subintr_skip_fifo
- nv_iord($r12, NV_PPWR_FIFO_INTR)
- push $r12
- mov $r14 (PROC_HOST & 0x0000ffff)
- sethi $r14 (PROC_HOST & 0xffff0000)
- mov $r13 KMSG_FIFO
- call(send)
- pop $r12
- nv_iowr(NV_PPWR_FIFO_INTR, $r12)
- intr_subintr_skip_fifo:
- nv_iowr(NV_PPWR_SUBINTR, $r9)
-
- intr_skip_subintr:
- and $r9 $r8 NV_PPWR_INTR_PAUSE
- bra z #intr_skip_pause
- and $r10 0xffbf
-
- intr_skip_pause:
- and $r9 $r8 NV_PPWR_INTR_USER0
- bra z #intr_skip_user0
- and $r10 0xffbf
-
- intr_skip_user0:
- nv_iowr(NV_PPWR_INTR_ACK, $r8)
- pop $r8
- mov $flags $r8
- pop $r15
- pop $r14
- pop $r13
- pop $r12
- pop $r11
- pop $r10
- pop $r9
- pop $r8
- pop $r0
- bclr $flags $p0
- iret
-
-// request the current process be sent a message after a timeout expires
-//
-// $r15 - current
-// $r14 - ticks
-// $r0 - zero
-timer:
- // interrupts off to prevent racing with timer isr
- bclr $flags ie0
-
- // if current process already has a timer set, bail
- ld b32 $r8 D[$r15 + #proc_time]
- cmp b32 $r8 0
- bra g #timer_done
- st b32 D[$r15 + #proc_time] $r14
-
- // halt watchdog timer temporarily and check for a pending
- // interrupt. if there's one already pending, we can just
- // bail since the timer isr will queue the next soonest
- // right after it's done
- nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r8)
- nv_iord($r8, NV_PPWR_INTR)
- and $r8 NV_PPWR_INTR_WATCHDOG
- bra nz #timer_enable
-
- // update the watchdog if this timer should expire first,
- // or if there's no timeout already set
- nv_iord($r8, NV_PPWR_WATCHDOG_TIME)
- cmp b32 $r14 $r0
- bra e #timer_reset
- cmp b32 $r14 $r8
- bra l #timer_done
- timer_reset:
- nv_iowr(NV_PPWR_WATCHDOG_TIME, $r14)
- st b32 D[$r0 + #time_prev] $r14
-
- // re-enable the watchdog timer
- timer_enable:
- mov $r8 1
- nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r8)
-
- // interrupts back on
- timer_done:
- bset $flags ie0
- ret
-
-// send message to another process
-//
-// $r15 - current
-// $r14 - process
-// $r13 - message
-// $r12 - message data 0
-// $r11 - message data 1
-// $r0 - zero
-send_proc:
- push $r8
- push $r9
- // check for space in queue
- ld b32 $r8 D[$r14 + #proc_qget]
- ld b32 $r9 D[$r14 + #proc_qput]
- xor $r8 #proc_qmaskb
- cmp b32 $r8 $r9
- bra e #send_done
-
- // enqueue message
- and $r8 $r9 #proc_qmaskp
- shl b32 $r8 $r8 #proc_qlen
- add b32 $r8 #proc_queue
- add b32 $r8 $r14
-
- ld b32 $r10 D[$r15 + #proc_id]
- st b32 D[$r8 + #msg_process] $r10
- st b32 D[$r8 + #msg_message] $r13
- st b32 D[$r8 + #msg_data0] $r12
- st b32 D[$r8 + #msg_data1] $r11
-
- // increment PUT
- add b32 $r9 1
- and $r9 #proc_qmaskf
- st b32 D[$r14 + #proc_qput] $r9
- bset $flags $p2
- send_done:
- pop $r9
- pop $r8
- ret
-
-// lookup process structure by its name
-//
-// $r15 - current
-// $r14 - process name
-// $r0 - zero
-//
-// $r14 - process
-// $p1 - success
-find:
- push $r8
- mov $r8 #proc_list_head
- bset $flags $p1
- find_loop:
- ld b32 $r10 D[$r8 + #proc_id]
- cmp b32 $r10 $r14
- bra e #find_done
- add b32 $r8 #proc_size
- cmp b32 $r8 #proc_list_tail
- bra ne #find_loop
- bclr $flags $p1
- find_done:
- mov b32 $r14 $r8
- pop $r8
- ret
-
-// send message to another process
-//
-// $r15 - current
-// $r14 - process id
-// $r13 - message
-// $r12 - message data 0
-// $r11 - message data 1
-// $r0 - zero
-send:
- call(find)
- bra $p1 #send_proc
- ret
-
-// process single message for a given process
-//
-// $r15 - current
-// $r14 - process
-// $r0 - zero
-recv:
- ld b32 $r8 D[$r14 + #proc_qget]
- ld b32 $r9 D[$r14 + #proc_qput]
- bclr $flags $p1
- cmp b32 $r8 $r9
- bra e #recv_done
- // dequeue message
- and $r9 $r8 #proc_qmaskp
- add b32 $r8 1
- and $r8 #proc_qmaskf
- st b32 D[$r14 + #proc_qget] $r8
- ld b32 $r10 D[$r14 + #proc_recv]
-
- push $r15
- mov $r15 $flags
- push $r15
- mov b32 $r15 $r14
-
- shl b32 $r9 $r9 #proc_qlen
- add b32 $r14 $r9
- add b32 $r14 #proc_queue
- ld b32 $r11 D[$r14 + #msg_data1]
- ld b32 $r12 D[$r14 + #msg_data0]
- ld b32 $r13 D[$r14 + #msg_message]
- ld b32 $r14 D[$r14 + #msg_process]
-
- // process it
- call $r10
- pop $r15
- mov $flags $r15
- bset $flags $p1
- pop $r15
- recv_done:
- ret
-
-init:
- // setup stack
- nv_iord($r1, NV_PPWR_CAPS)
- extr $r1 $r1 9:17
- shl b32 $r1 8
- mov $sp $r1
-
-#ifdef NVKM_FALCON_MMIO_UAS
- // somehow allows the magic "access mmio via D[]" stuff that's
- // used by the nv_rd32/nv_wr32 macros to work
- mov $r1 0x0010
- sethi $r1 NV_PPWR_UAS_CONFIG_ENABLE
- nv_iowrs(NV_PPWR_UAS_CONFIG, $r1)
-#endif
-
- // route all interrupts except user0/1 and pause to fuc
- mov $r1 0x00e0
- sethi $r1 0x00000000
- nv_iowr(NV_PPWR_INTR_ROUTE, $r1)
-
- // enable watchdog and subintr intrs
- mov $r1 NV_PPWR_INTR_EN_CLR_MASK
- nv_iowr(NV_PPWR_INTR_EN_CLR, $r1)
- mov $r1 NV_PPWR_INTR_EN_SET_WATCHDOG
- or $r1 NV_PPWR_INTR_EN_SET_SUBINTR
- nv_iowr(NV_PPWR_INTR_EN_SET, $r1)
-
- // enable interrupts globally
- mov $r1 #intr
- sethi $r1 0x00000000
- mov $iv0 $r1
- bset $flags ie0
-
- // enable watchdog timer
- mov $r1 1
- nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r1)
-
- // bootstrap processes, idle process will be last, and not return
- mov $r15 #proc_list_head
- init_proc:
- ld b32 $r1 D[$r15 + #proc_init]
- cmp b32 $r1 0
- bra z #init_proc
- call $r1
- add b32 $r15 #proc_size
- bra #init_proc
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc
deleted file mode 100644
index 2a74ea9..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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 GT215 0xa3
-#define GF100 0xc0
-#define GF119 0xd9
-#define GK208 0x108
-
-#include "os.h"
-
-// IO addresses
-#define NV_PPWR_INTR_TRIGGER 0x0000
-#define NV_PPWR_INTR_TRIGGER_USER1 0x00000080
-#define NV_PPWR_INTR_TRIGGER_USER0 0x00000040
-#define NV_PPWR_INTR_ACK 0x0004
-#define NV_PPWR_INTR_ACK_SUBINTR 0x00000800
-#define NV_PPWR_INTR_ACK_WATCHDOG 0x00000002
-#define NV_PPWR_INTR 0x0008
-#define NV_PPWR_INTR_SUBINTR 0x00000800
-#define NV_PPWR_INTR_USER1 0x00000080
-#define NV_PPWR_INTR_USER0 0x00000040
-#define NV_PPWR_INTR_PAUSE 0x00000020
-#define NV_PPWR_INTR_WATCHDOG 0x00000002
-#define NV_PPWR_INTR_EN_SET 0x0010
-#define NV_PPWR_INTR_EN_SET_SUBINTR 0x00000800
-#define NV_PPWR_INTR_EN_SET_WATCHDOG 0x00000002
-#define NV_PPWR_INTR_EN_CLR 0x0014
-#define NV_PPWR_INTR_EN_CLR_MASK /* fuck i hate envyas */ -1
-#define NV_PPWR_INTR_ROUTE 0x001c
-#define NV_PPWR_TIMER_LOW 0x002c
-#define NV_PPWR_WATCHDOG_TIME 0x0034
-#define NV_PPWR_WATCHDOG_ENABLE 0x0038
-#define NV_PPWR_CAPS 0x0108
-#define NV_PPWR_UAS_CONFIG 0x0164
-#define NV_PPWR_UAS_CONFIG_ENABLE 0x00010000
-#if NVKM_PPWR_CHIPSET >= GK208
-#define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x0450)
-#endif
-#define NV_PPWR_FIFO_PUT(i) (4 * (i) + 0x04a0)
-#define NV_PPWR_FIFO_GET(i) (4 * (i) + 0x04b0)
-#define NV_PPWR_FIFO_INTR 0x04c0
-#define NV_PPWR_FIFO_INTR_EN 0x04c4
-#define NV_PPWR_RFIFO_PUT 0x04c8
-#define NV_PPWR_RFIFO_GET 0x04cc
-#define NV_PPWR_H2D 0x04d0
-#define NV_PPWR_D2H 0x04dc
-#if NVKM_PPWR_CHIPSET < GK208
-#define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x05d0)
-#endif
-#define NV_PPWR_SUBINTR 0x0688
-#define NV_PPWR_SUBINTR_FIFO 0x00000002
-#define NV_PPWR_MMIO_ADDR 0x07a0
-#define NV_PPWR_MMIO_DATA 0x07a4
-#define NV_PPWR_MMIO_CTRL 0x07ac
-#define NV_PPWR_MMIO_CTRL_TRIGGER 0x00010000
-#define NV_PPWR_MMIO_CTRL_STATUS 0x00007000
-#define NV_PPWR_MMIO_CTRL_STATUS_IDLE 0x00000000
-#define NV_PPWR_MMIO_CTRL_MASK 0x000000f0
-#define NV_PPWR_MMIO_CTRL_MASK_B32_0 0x000000f0
-#define NV_PPWR_MMIO_CTRL_OP 0x00000003
-#define NV_PPWR_MMIO_CTRL_OP_RD 0x00000001
-#define NV_PPWR_MMIO_CTRL_OP_WR 0x00000002
-#define NV_PPWR_OUTPUT 0x07c0
-#define NV_PPWR_OUTPUT_FB_PAUSE 0x00000004
-#define NV_PPWR_OUTPUT_SET 0x07e0
-#define NV_PPWR_OUTPUT_SET_FB_PAUSE 0x00000004
-#define NV_PPWR_OUTPUT_CLR 0x07e4
-#define NV_PPWR_OUTPUT_CLR_FB_PAUSE 0x00000004
-
-// Inter-process message format
-.equ #msg_process 0x00 /* send() target, recv() sender */
-.equ #msg_message 0x04
-.equ #msg_data0 0x08
-.equ #msg_data1 0x0c
-
-// Kernel message IDs
-#define KMSG_FIFO 0x00000000
-#define KMSG_ALARM 0x00000001
-
-// Process message queue description
-.equ #proc_qlen 4 // log2(size of queue entry in bytes)
-.equ #proc_qnum 2 // log2(max number of entries in queue)
-.equ #proc_qmaskb (1 << #proc_qnum) // max number of entries in queue
-.equ #proc_qmaskp (#proc_qmaskb - 1)
-.equ #proc_qmaskf ((#proc_qmaskb << 1) - 1)
-.equ #proc_qsize (1 << (#proc_qlen + #proc_qnum))
-
-// Process table entry
-.equ #proc_id 0x00
-.equ #proc_init 0x04
-.equ #proc_recv 0x08
-.equ #proc_time 0x0c
-.equ #proc_qput 0x10
-.equ #proc_qget 0x14
-.equ #proc_queue 0x18
-.equ #proc_size (0x18 + #proc_qsize)
-
-#define process(id,init,recv) /*
-*/ .b32 id /*
-*/ .b32 init /*
-*/ .b32 recv /*
-*/ .b32 0 /*
-*/ .b32 0 /*
-*/ .b32 0 /*
-*/ .skip 64
-
-#ifndef NVKM_FALCON_UNSHIFTED_IO
-#define nv_iord(reg,ior) /*
-*/ mov reg ior /*
-*/ shl b32 reg 6 /*
-*/ iord reg I[reg + 0x000]
-#else
-#define nv_iord(reg,ior) /*
-*/ mov reg ior /*
-*/ iord reg I[reg + 0x000]
-#endif
-
-#ifndef NVKM_FALCON_UNSHIFTED_IO
-#define nv_iowr(ior,reg) /*
-*/ mov $r0 ior /*
-*/ shl b32 $r0 6 /*
-*/ iowr I[$r0 + 0x000] reg /*
-*/ clear b32 $r0
-#else
-#define nv_iowr(ior,reg) /*
-*/ mov $r0 ior /*
-*/ iowr I[$r0 + 0x000] reg /*
-*/ clear b32 $r0
-#endif
-
-#ifndef NVKM_FALCON_UNSHIFTED_IO
-#define nv_iowrs(ior,reg) /*
-*/ mov $r0 ior /*
-*/ shl b32 $r0 6 /*
-*/ iowrs I[$r0 + 0x000] reg /*
-*/ clear b32 $r0
-#else
-#define nv_iowrs(ior,reg) /*
-*/ mov $r0 ior /*
-*/ iowrs I[$r0 + 0x000] reg /*
-*/ clear b32 $r0
-#endif
-
-#define hash #
-#define fn(a) a
-#ifndef NVKM_FALCON_PC24
-#define call(a) call fn(hash)a
-#else
-#define call(a) lcall fn(hash)a
-#endif
-
-#ifndef NVKM_FALCON_MMIO_UAS
-#define nv_rd32(reg,addr) /*
-*/ mov b32 $r14 addr /*
-*/ call(rd32) /*
-*/ mov b32 reg $r13
-#else
-#define nv_rd32(reg,addr) /*
-*/ sethi $r0 0x14000000 /*
-*/ or $r0 addr /*
-*/ ld b32 reg D[$r0] /*
-*/ clear b32 $r0
-#endif
-
-#if !defined(NVKM_FALCON_MMIO_UAS) || defined(NVKM_FALCON_MMIO_TRAP)
-#define nv_wr32(addr,reg) /*
-*/ push addr /*
-*/ push reg /*
-*/ pop $r13 /*
-*/ pop $r14 /*
-*/ call(wr32) /*
-#else
-#define nv_wr32(addr,reg) /*
-*/ sethi $r0 0x14000000 /*
-*/ or $r0 addr /*
-*/ st b32 D[$r0] reg /*
-*/ clear b32 $r0
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
deleted file mode 100644
index d43741e..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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
- */
-
-#ifdef INCLUDE_PROC
-process(PROC_MEMX, #memx_init, #memx_recv)
-#endif
-
-/******************************************************************************
- * MEMX data segment
- *****************************************************************************/
-#ifdef INCLUDE_DATA
-.equ #memx_opcode 0
-.equ #memx_header 2
-.equ #memx_length 4
-.equ #memx_func 8
-
-#define handler(cmd,hdr,len,func) /*
-*/ .b16 MEMX_##cmd /*
-*/ .b16 hdr /*
-*/ .b16 len /*
-*/ .b16 0 /*
-*/ .b32 func
-
-memx_func_head:
-handler(ENTER , 0x0001, 0x0000, #memx_func_enter)
-memx_func_next:
-handler(LEAVE , 0x0000, 0x0000, #memx_func_leave)
-handler(WR32 , 0x0000, 0x0002, #memx_func_wr32)
-handler(WAIT , 0x0004, 0x0000, #memx_func_wait)
-handler(DELAY , 0x0001, 0x0000, #memx_func_delay)
-memx_func_tail:
-
-.equ #memx_func_size #memx_func_next - #memx_func_head
-.equ #memx_func_num (#memx_func_tail - #memx_func_head) / #memx_func_size
-
-memx_data_head:
-.skip 0x0800
-memx_data_tail:
-#endif
-
-/******************************************************************************
- * MEMX code segment
- *****************************************************************************/
-#ifdef INCLUDE_CODE
-// description
-//
-// $r15 - current (memx)
-// $r4 - packet length
-// +00: bitmask of heads to wait for vblank on
-// $r3 - opcode desciption
-// $r0 - zero
-memx_func_enter:
- mov $r6 NV_PPWR_OUTPUT_SET_FB_PAUSE
- nv_iowr(NV_PPWR_OUTPUT_SET, $r6)
- memx_func_enter_wait:
- nv_iord($r6, NV_PPWR_OUTPUT)
- and $r6 NV_PPWR_OUTPUT_FB_PAUSE
- bra z #memx_func_enter_wait
- //XXX: TODO
- ld b32 $r6 D[$r1 + 0x00]
- add b32 $r1 0x04
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r4 - packet length
-// $r3 - opcode desciption
-// $r0 - zero
-memx_func_leave:
- mov $r6 NV_PPWR_OUTPUT_CLR_FB_PAUSE
- nv_iowr(NV_PPWR_OUTPUT_CLR, $r6)
- memx_func_leave_wait:
- nv_iord($r6, NV_PPWR_OUTPUT)
- and $r6 NV_PPWR_OUTPUT_FB_PAUSE
- bra nz #memx_func_leave_wait
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r4 - packet length
-// +00*n: addr
-// +04*n: data
-// $r3 - opcode desciption
-// $r0 - zero
-memx_func_wr32:
- ld b32 $r6 D[$r1 + 0x00]
- ld b32 $r5 D[$r1 + 0x04]
- add b32 $r1 0x08
- nv_wr32($r6, $r5)
- sub b32 $r4 0x02
- bra nz #memx_func_wr32
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r4 - packet length
-// +00: addr
-// +04: mask
-// +08: data
-// +0c: timeout (ns)
-// $r3 - opcode desciption
-// $r0 - zero
-memx_func_wait:
- nv_iord($r8, NV_PPWR_TIMER_LOW)
- ld b32 $r14 D[$r1 + 0x00]
- ld b32 $r13 D[$r1 + 0x04]
- ld b32 $r12 D[$r1 + 0x08]
- ld b32 $r11 D[$r1 + 0x0c]
- add b32 $r1 0x10
- call(wait)
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r4 - packet length
-// +00: time (ns)
-// $r3 - opcode desciption
-// $r0 - zero
-memx_func_delay:
- ld b32 $r14 D[$r1 + 0x00]
- add b32 $r1 0x04
- call(nsec)
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r14 - sender process name
-// $r13 - message (exec)
-// $r12 - head of script
-// $r11 - tail of script
-// $r0 - zero
-memx_exec:
- push $r14
- push $r13
- mov b32 $r1 $r12
- mov b32 $r2 $r11
- memx_exec_next:
- // fetch the packet header, and locate opcode info
- ld b32 $r3 D[$r1]
- add b32 $r1 4
- shr b32 $r4 $r3 16
- mulu $r3 #memx_func_size
-
- // execute the opcode handler
- ld b32 $r5 D[$r3 + #memx_func_head + #memx_func]
- call $r5
-
- // keep going, if we haven't reached the end
- cmp b32 $r1 $r2
- bra l #memx_exec_next
-
- // send completion reply
- pop $r13
- pop $r14
- call(send)
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r14 - sender process name
-// $r13 - message
-// $r12 - data0
-// $r11 - data1
-// $r0 - zero
-memx_info:
- mov $r12 #memx_data_head
- mov $r11 #memx_data_tail - #memx_data_head
- call(send)
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r14 - sender process name
-// $r13 - message
-// $r12 - data0
-// $r11 - data1
-// $r0 - zero
-memx_recv:
- cmp b32 $r13 MEMX_MSG_EXEC
- bra e #memx_exec
- cmp b32 $r13 MEMX_MSG_INFO
- bra e #memx_info
- ret
-
-// description
-//
-// $r15 - current (memx)
-// $r0 - zero
-memx_init:
- ret
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc
deleted file mode 100644
index 947be53..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 NVKM_PPWR_CHIPSET GK208
-
-#define NVKM_FALCON_PC24
-#define NVKM_FALCON_UNSHIFTED_IO
-//#define NVKM_FALCON_MMIO_UAS
-//#define NVKM_FALCON_MMIO_TRAP
-
-#include "macros.fuc"
-
-.section #nv108_pwr_data
-#define INCLUDE_PROC
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_PROC
-
-#define INCLUDE_DATA
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_DATA
-.align 256
-
-.section #nv108_pwr_code
-#define INCLUDE_CODE
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_CODE
-.align 256
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
deleted file mode 100644
index 9342e2d..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
+++ /dev/null
@@ -1,1165 +0,0 @@
-uint32_t nv108_pwr_data[] = {
-/* 0x0000: proc_kern */
- 0x52544e49,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0058: proc_list_head */
- 0x54534f48,
- 0x00000379,
- 0x0000032a,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x584d454d,
- 0x0000046f,
- 0x00000461,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x46524550,
- 0x00000473,
- 0x00000471,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x54534554,
- 0x00000494,
- 0x00000475,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x454c4449,
- 0x0000049f,
- 0x0000049d,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0210: proc_list_tail */
-/* 0x0210: time_prev */
- 0x00000000,
-/* 0x0214: time_next */
- 0x00000000,
-/* 0x0218: fifo_queue */
- 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,
-/* 0x0298: rfifo_queue */
- 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,
-/* 0x0318: memx_func_head */
- 0x00010000,
- 0x00000000,
- 0x000003a9,
-/* 0x0324: memx_func_next */
- 0x00000001,
- 0x00000000,
- 0x000003c7,
- 0x00000002,
- 0x00000002,
- 0x000003df,
- 0x00040003,
- 0x00000000,
- 0x00000407,
- 0x00010004,
- 0x00000000,
- 0x00000421,
-/* 0x0354: memx_func_tail */
-/* 0x0354: memx_data_head */
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0b54: memx_data_tail */
- 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,
-};
-
-uint32_t nv108_pwr_code[] = {
- 0x02910ef5,
-/* 0x0004: rd32 */
- 0xf607a040,
- 0x04bd000e,
- 0xe3f0010e,
- 0x07ac4001,
- 0xbd000ef6,
-/* 0x0019: rd32_wait */
- 0x07ac4e04,
- 0xf100eecf,
- 0xf47000e4,
- 0xa44df61b,
- 0x00ddcf07,
-/* 0x002e: wr32 */
- 0xa04000f8,
- 0x000ef607,
- 0xa44004bd,
- 0x000df607,
- 0x020e04bd,
- 0xf0f0e5f0,
- 0xac4001e3,
- 0x000ef607,
-/* 0x004e: wr32_wait */
- 0xac4e04bd,
- 0x00eecf07,
- 0x7000e4f1,
- 0xf8f61bf4,
-/* 0x005d: nsec */
- 0xcf2c0800,
-/* 0x0062: nsec_loop */
- 0x2c090088,
- 0xbb0099cf,
- 0x9ea60298,
- 0xf8f61ef4,
-/* 0x0071: wait */
- 0xcf2c0800,
-/* 0x0076: wait_loop */
- 0xeeb20088,
- 0x0000047e,
- 0xadfddab2,
- 0xf4aca604,
- 0x2c09100b,
- 0xbb0099cf,
- 0x9ba60298,
-/* 0x0093: wait_done */
- 0xf8e61ef4,
-/* 0x0095: intr_watchdog */
- 0x03e99800,
- 0xf40096b0,
- 0x0a98280b,
- 0x029abb84,
- 0x0d0e1cf4,
- 0x01de7e01,
- 0xf494bd00,
-/* 0x00b2: intr_watchdog_next_time */
- 0x0a98140e,
- 0x00a6b085,
- 0xa6080bf4,
- 0x061cf49a,
-/* 0x00c0: intr_watchdog_next_time_set */
-/* 0x00c3: intr_watchdog_next_proc */
- 0xb58509b5,
- 0xe0b603e9,
- 0x10e6b158,
- 0xc81bf402,
-/* 0x00d2: intr */
- 0x00f900f8,
- 0x80f904bd,
- 0xa0f990f9,
- 0xc0f9b0f9,
- 0xe0f9d0f9,
- 0x000ff0f9,
- 0xf90188fe,
- 0x04504880,
- 0xb60088cf,
- 0x50400180,
- 0x0008f604,
- 0x080804bd,
- 0xc40088cf,
- 0x0bf40289,
- 0x8500b51f,
- 0x957e580e,
- 0x09980000,
- 0x0096b085,
- 0x000d0bf4,
- 0x0009f634,
- 0x09b504bd,
-/* 0x0125: intr_skip_watchdog */
- 0x0089e484,
- 0x360bf408,
- 0xcf068849,
- 0x9ac40099,
- 0x220bf402,
- 0xcf04c04c,
- 0xc0f900cc,
- 0xf14f484e,
- 0x0d5453e3,
- 0x023f7e00,
- 0x40c0fc00,
- 0x0cf604c0,
-/* 0x0157: intr_subintr_skip_fifo */
- 0x4004bd00,
- 0x09f60688,
-/* 0x015f: intr_skip_subintr */
- 0xc404bd00,
- 0x0bf42089,
- 0xbfa4f107,
-/* 0x0169: intr_skip_pause */
- 0x4089c4ff,
- 0xf1070bf4,
-/* 0x0173: intr_skip_user0 */
- 0x00ffbfa4,
- 0x0008f604,
- 0x80fc04bd,
- 0xfc0088fe,
- 0xfce0fcf0,
- 0xfcc0fcd0,
- 0xfca0fcb0,
- 0xfc80fc90,
- 0x0032f400,
-/* 0x0196: timer */
- 0x32f401f8,
- 0x03f89810,
- 0xf40086b0,
- 0xfeb53a1c,
- 0xf6380003,
- 0x04bd0008,
- 0x88cf0808,
- 0x0284f000,
- 0x081c1bf4,
- 0x0088cf34,
- 0x0bf4e0a6,
- 0xf4e8a608,
-/* 0x01c6: timer_reset */
- 0x3400161e,
- 0xbd000ef6,
- 0x840eb504,
-/* 0x01d0: timer_enable */
- 0x38000108,
- 0xbd0008f6,
-/* 0x01d9: timer_done */
- 0x1031f404,
-/* 0x01de: send_proc */
- 0x80f900f8,
- 0xe89890f9,
- 0x04e99805,
- 0xa60486f0,
- 0x2a0bf489,
- 0x940398c4,
- 0x80b60488,
- 0x008ebb18,
- 0xb500fa98,
- 0x8db5008a,
- 0x028cb501,
- 0xb6038bb5,
- 0x94f00190,
- 0x04e9b507,
-/* 0x0217: send_done */
- 0xfc0231f4,
- 0xf880fc90,
-/* 0x021d: find */
- 0x0880f900,
- 0x0131f458,
-/* 0x0224: find_loop */
- 0xa6008a98,
- 0x100bf4ae,
- 0xb15880b6,
- 0xf4021086,
- 0x32f4f11b,
-/* 0x0239: find_done */
- 0xfc8eb201,
-/* 0x023f: send */
- 0x7e00f880,
- 0xf400021d,
- 0x00f89b01,
-/* 0x0248: recv */
- 0x9805e898,
- 0x32f404e9,
- 0xf489a601,
- 0x89c43c0b,
- 0x0180b603,
- 0xb50784f0,
- 0xea9805e8,
- 0xfef0f902,
- 0xf0f9018f,
- 0x9994efb2,
- 0x00e9bb04,
- 0x9818e0b6,
- 0xec9803eb,
- 0x01ed9802,
- 0xf900ee98,
- 0xfef0fca5,
- 0x31f400f8,
-/* 0x028f: recv_done */
- 0xf8f0fc01,
-/* 0x0291: init */
- 0x01084100,
- 0xe70011cf,
- 0xb6010911,
- 0x14fe0814,
- 0x00e04100,
- 0x000013f0,
- 0x0001f61c,
- 0xff0104bd,
- 0x01f61400,
- 0x0104bd00,
- 0x0015f102,
- 0xf6100008,
- 0x04bd0001,
- 0xf000d241,
- 0x10fe0013,
- 0x1031f400,
- 0x38000101,
- 0xbd0001f6,
-/* 0x02db: init_proc */
- 0x98580f04,
- 0x16b001f1,
- 0xfa0bf400,
- 0xf0b615f9,
- 0xf20ef458,
-/* 0x02ec: host_send */
- 0xcf04b041,
- 0xa0420011,
- 0x0022cf04,
- 0x0bf412a6,
- 0x071ec42e,
- 0xb704ee94,
- 0x980218e0,
- 0xec9803eb,
- 0x01ed9802,
- 0x7e00ee98,
- 0xb600023f,
- 0x1ec40110,
- 0x04b0400f,
- 0xbd0001f6,
- 0xc70ef404,
-/* 0x0328: host_send_done */
-/* 0x032a: host_recv */
- 0x494100f8,
- 0x5413f14e,
- 0xf4e1a652,
-/* 0x0336: host_recv_wait */
- 0xcc41b90b,
- 0x0011cf04,
- 0xcf04c842,
- 0x16f00022,
- 0xf412a608,
- 0x23c4ef0b,
- 0x0434b607,
- 0x029830b7,
- 0xb5033bb5,
- 0x3db5023c,
- 0x003eb501,
- 0xf00120b6,
- 0xc8400f24,
- 0x0002f604,
- 0x400204bd,
- 0x02f60000,
- 0xf804bd00,
-/* 0x0379: host_init */
- 0x00804100,
- 0xf11014b6,
- 0x40021815,
- 0x01f604d0,
- 0x4104bd00,
- 0x14b60080,
- 0x9815f110,
- 0x04dc4002,
- 0xbd0001f6,
- 0x40010104,
- 0x01f604c4,
- 0xf804bd00,
-/* 0x03a9: memx_func_enter */
- 0x40040600,
- 0x06f607e0,
-/* 0x03b3: memx_func_enter_wait */
- 0x4604bd00,
- 0x66cf07c0,
- 0x0464f000,
- 0x98f70bf4,
- 0x10b60016,
-/* 0x03c7: memx_func_leave */
- 0x0600f804,
- 0x07e44004,
- 0xbd0006f6,
-/* 0x03d1: memx_func_leave_wait */
- 0x07c04604,
- 0xf00066cf,
- 0x1bf40464,
-/* 0x03df: memx_func_wr32 */
- 0x9800f8f7,
- 0x15980016,
- 0x0810b601,
- 0x50f960f9,
- 0xe0fcd0fc,
- 0x00002e7e,
- 0x140003f1,
- 0xa00506fd,
- 0xb604bd05,
- 0x1bf40242,
-/* 0x0407: memx_func_wait */
- 0x0800f8dd,
- 0x0088cf2c,
- 0x98001e98,
- 0x1c98011d,
- 0x031b9802,
- 0x7e1010b6,
- 0xf8000071,
-/* 0x0421: memx_func_delay */
- 0x001e9800,
- 0x7e0410b6,
- 0xf800005d,
-/* 0x042d: memx_exec */
- 0xf9e0f900,
- 0xb2c1b2d0,
-/* 0x0435: memx_exec_next */
- 0x001398b2,
- 0x950410b6,
- 0x30f01034,
- 0xc835980c,
- 0x12a655f9,
- 0xfced1ef4,
- 0x7ee0fcd0,
- 0xf800023f,
-/* 0x0455: memx_info */
- 0x03544c00,
- 0x7e08004b,
- 0xf800023f,
-/* 0x0461: memx_recv */
- 0x01d6b000,
- 0xb0c90bf4,
- 0x0bf400d6,
-/* 0x046f: memx_init */
- 0xf800f8eb,
-/* 0x0471: perf_recv */
-/* 0x0473: perf_init */
- 0xf800f800,
-/* 0x0475: test_recv */
- 0x04584100,
- 0xb60011cf,
- 0x58400110,
- 0x0001f604,
- 0xe7f104bd,
- 0xe3f1d900,
- 0x967e134f,
- 0x00f80001,
-/* 0x0494: test_init */
- 0x7e08004e,
- 0xf8000196,
-/* 0x049d: idle_recv */
-/* 0x049f: idle */
- 0xf400f800,
- 0x54410031,
- 0x0011cf04,
- 0x400110b6,
- 0x01f60454,
-/* 0x04b3: idle_loop */
- 0x0104bd00,
- 0x0232f458,
-/* 0x04b8: idle_proc */
-/* 0x04b8: idle_proc_exec */
- 0x1eb210f9,
- 0x0002487e,
- 0x11f410fc,
- 0x0231f409,
-/* 0x04cb: idle_proc_next */
- 0xb6f00ef4,
- 0x1fa65810,
- 0xf4e81bf4,
- 0x28f4e002,
- 0xc60ef400,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc
deleted file mode 100644
index 6fde0b8..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 NVKM_PPWR_CHIPSET GT215
-
-//#define NVKM_FALCON_PC24
-//#define NVKM_FALCON_UNSHIFTED_IO
-//#define NVKM_FALCON_MMIO_UAS
-//#define NVKM_FALCON_MMIO_TRAP
-
-#include "macros.fuc"
-
-.section #nva3_pwr_data
-#define INCLUDE_PROC
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_PROC
-
-#define INCLUDE_DATA
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_DATA
-.align 256
-
-.section #nva3_pwr_code
-#define INCLUDE_CODE
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_CODE
-.align 256
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
deleted file mode 100644
index 0fa4d7d..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
+++ /dev/null
@@ -1,1229 +0,0 @@
-uint32_t nva3_pwr_data[] = {
-/* 0x0000: proc_kern */
- 0x52544e49,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0058: proc_list_head */
- 0x54534f48,
- 0x00000430,
- 0x000003cd,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x584d454d,
- 0x0000054e,
- 0x00000540,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x46524550,
- 0x00000552,
- 0x00000550,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x54534554,
- 0x0000057b,
- 0x00000554,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x454c4449,
- 0x00000587,
- 0x00000585,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0210: proc_list_tail */
-/* 0x0210: time_prev */
- 0x00000000,
-/* 0x0214: time_next */
- 0x00000000,
-/* 0x0218: fifo_queue */
- 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,
-/* 0x0298: rfifo_queue */
- 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,
-/* 0x0318: memx_func_head */
- 0x00010000,
- 0x00000000,
- 0x0000046f,
-/* 0x0324: memx_func_next */
- 0x00000001,
- 0x00000000,
- 0x00000496,
- 0x00000002,
- 0x00000002,
- 0x000004b7,
- 0x00040003,
- 0x00000000,
- 0x000004df,
- 0x00010004,
- 0x00000000,
- 0x000004fc,
-/* 0x0354: memx_func_tail */
-/* 0x0354: memx_data_head */
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0b54: memx_data_tail */
- 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,
-};
-
-uint32_t nva3_pwr_code[] = {
- 0x030d0ef5,
-/* 0x0004: rd32 */
- 0x07a007f1,
- 0xd00604b6,
- 0x04bd000e,
- 0xf001e7f0,
- 0x07f101e3,
- 0x04b607ac,
- 0x000ed006,
-/* 0x0022: rd32_wait */
- 0xe7f104bd,
- 0xe4b607ac,
- 0x00eecf06,
- 0x7000e4f1,
- 0xf1f21bf4,
- 0xb607a4d7,
- 0xddcf06d4,
-/* 0x003f: wr32 */
- 0xf100f800,
- 0xb607a007,
- 0x0ed00604,
- 0xf104bd00,
- 0xb607a407,
- 0x0dd00604,
- 0xf004bd00,
- 0xe5f002e7,
- 0x01e3f0f0,
- 0x07ac07f1,
- 0xd00604b6,
- 0x04bd000e,
-/* 0x006c: wr32_wait */
- 0x07ace7f1,
- 0xcf06e4b6,
- 0xe4f100ee,
- 0x1bf47000,
-/* 0x007f: nsec */
- 0xf000f8f2,
- 0x84b62c87,
- 0x0088cf06,
-/* 0x0088: nsec_loop */
- 0xb62c97f0,
- 0x99cf0694,
- 0x0298bb00,
- 0xf4069eb8,
- 0x00f8f11e,
-/* 0x009c: wait */
- 0xb62c87f0,
- 0x88cf0684,
-/* 0x00a5: wait_loop */
- 0x02eeb900,
- 0xb90421f4,
- 0xadfd02da,
- 0x06acb804,
- 0xf0150bf4,
- 0x94b62c97,
- 0x0099cf06,
- 0xb80298bb,
- 0x1ef4069b,
-/* 0x00c9: wait_done */
-/* 0x00cb: intr_watchdog */
- 0x9800f8df,
- 0x96b003e9,
- 0x2a0bf400,
- 0xbb840a98,
- 0x1cf4029a,
- 0x01d7f00f,
- 0x025421f5,
- 0x0ef494bd,
-/* 0x00e9: intr_watchdog_next_time */
- 0x850a9815,
- 0xf400a6b0,
- 0x9ab8090b,
- 0x061cf406,
-/* 0x00f8: intr_watchdog_next_time_set */
-/* 0x00fb: intr_watchdog_next_proc */
- 0x80850980,
- 0xe0b603e9,
- 0x10e6b158,
- 0xc61bf402,
-/* 0x010a: intr */
- 0x00f900f8,
- 0x80f904bd,
- 0xa0f990f9,
- 0xc0f9b0f9,
- 0xe0f9d0f9,
- 0xf7f0f0f9,
- 0x0188fe00,
- 0x87f180f9,
- 0x84b605d0,
- 0x0088cf06,
- 0xf10180b6,
- 0xb605d007,
- 0x08d00604,
- 0xf004bd00,
- 0x84b60887,
- 0x0088cf06,
- 0xf40289c4,
- 0x0080230b,
- 0x58e7f085,
- 0x98cb21f4,
- 0x96b08509,
- 0x110bf400,
- 0xb63407f0,
- 0x09d00604,
- 0x8004bd00,
-/* 0x016e: intr_skip_watchdog */
- 0x89e48409,
- 0x0bf40800,
- 0x8897f148,
- 0x0694b606,
- 0xc40099cf,
- 0x0bf4029a,
- 0xc0c7f12c,
- 0x06c4b604,
- 0xf900cccf,
- 0x48e7f1c0,
- 0x53e3f14f,
- 0x00d7f054,
- 0x02b921f5,
- 0x07f1c0fc,
- 0x04b604c0,
- 0x000cd006,
-/* 0x01ae: intr_subintr_skip_fifo */
- 0x07f104bd,
- 0x04b60688,
- 0x0009d006,
-/* 0x01ba: intr_skip_subintr */
- 0x89c404bd,
- 0x070bf420,
- 0xffbfa4f1,
-/* 0x01c4: intr_skip_pause */
- 0xf44089c4,
- 0xa4f1070b,
-/* 0x01ce: intr_skip_user0 */
- 0x07f0ffbf,
- 0x0604b604,
- 0xbd0008d0,
- 0xfe80fc04,
- 0xf0fc0088,
- 0xd0fce0fc,
- 0xb0fcc0fc,
- 0x90fca0fc,
- 0x00fc80fc,
- 0xf80032f4,
-/* 0x01f5: timer */
- 0x1032f401,
- 0xb003f898,
- 0x1cf40086,
- 0x03fe8051,
- 0xb63807f0,
- 0x08d00604,
- 0xf004bd00,
- 0x84b60887,
- 0x0088cf06,
- 0xf40284f0,
- 0x87f0261b,
- 0x0684b634,
- 0xb80088cf,
- 0x0bf406e0,
- 0x06e8b809,
-/* 0x0233: timer_reset */
- 0xf01f1ef4,
- 0x04b63407,
- 0x000ed006,
- 0x0e8004bd,
-/* 0x0241: timer_enable */
- 0x0187f084,
- 0xb63807f0,
- 0x08d00604,
-/* 0x024f: timer_done */
- 0xf404bd00,
- 0x00f81031,
-/* 0x0254: send_proc */
- 0x90f980f9,
- 0x9805e898,
- 0x86f004e9,
- 0x0689b804,
- 0xc42a0bf4,
- 0x88940398,
- 0x1880b604,
- 0x98008ebb,
- 0x8a8000fa,
- 0x018d8000,
- 0x80028c80,
- 0x90b6038b,
- 0x0794f001,
- 0xf404e980,
-/* 0x028e: send_done */
- 0x90fc0231,
- 0x00f880fc,
-/* 0x0294: find */
- 0x87f080f9,
- 0x0131f458,
-/* 0x029c: find_loop */
- 0xb8008a98,
- 0x0bf406ae,
- 0x5880b610,
- 0x021086b1,
- 0xf4f01bf4,
-/* 0x02b2: find_done */
- 0x8eb90132,
- 0xf880fc02,
-/* 0x02b9: send */
- 0x9421f500,
- 0x9701f402,
-/* 0x02c2: recv */
- 0xe89800f8,
- 0x04e99805,
- 0xb80132f4,
- 0x0bf40689,
- 0x0389c43d,
- 0xf00180b6,
- 0xe8800784,
- 0x02ea9805,
- 0x8ffef0f9,
- 0xb9f0f901,
- 0x999402ef,
- 0x00e9bb04,
- 0x9818e0b6,
- 0xec9803eb,
- 0x01ed9802,
- 0xf900ee98,
- 0xfef0fca5,
- 0x31f400f8,
-/* 0x030b: recv_done */
- 0xf8f0fc01,
-/* 0x030d: init */
- 0x0817f100,
- 0x0614b601,
- 0xe70011cf,
- 0xb6010911,
- 0x14fe0814,
- 0xe017f100,
- 0x0013f000,
- 0xb61c07f0,
- 0x01d00604,
- 0xf004bd00,
- 0x07f0ff17,
- 0x0604b614,
- 0xbd0001d0,
- 0x0217f004,
- 0x080015f1,
- 0xb61007f0,
- 0x01d00604,
- 0xf104bd00,
- 0xf0010a17,
- 0x10fe0013,
- 0x1031f400,
- 0xf00117f0,
- 0x04b63807,
- 0x0001d006,
- 0xf7f004bd,
-/* 0x0371: init_proc */
- 0x01f19858,
- 0xf40016b0,
- 0x15f9fa0b,
- 0xf458f0b6,
-/* 0x0382: host_send */
- 0x17f1f20e,
- 0x14b604b0,
- 0x0011cf06,
- 0x04a027f1,
- 0xcf0624b6,
- 0x12b80022,
- 0x320bf406,
- 0x94071ec4,
- 0xe0b704ee,
- 0xeb980218,
- 0x02ec9803,
- 0x9801ed98,
- 0x21f500ee,
- 0x10b602b9,
- 0x0f1ec401,
- 0x04b007f1,
- 0xd00604b6,
- 0x04bd0001,
-/* 0x03cb: host_send_done */
- 0xf8ba0ef4,
-/* 0x03cd: host_recv */
- 0x4917f100,
- 0x5413f14e,
- 0x06e1b852,
-/* 0x03db: host_recv_wait */
- 0xf1aa0bf4,
- 0xb604cc17,
- 0x11cf0614,
- 0xc827f100,
- 0x0624b604,
- 0xf00022cf,
- 0x12b80816,
- 0xe60bf406,
- 0xb60723c4,
- 0x30b70434,
- 0x3b800298,
- 0x023c8003,
- 0x80013d80,
- 0x20b6003e,
- 0x0f24f001,
- 0x04c807f1,
- 0xd00604b6,
- 0x04bd0002,
- 0xf04027f0,
- 0x04b60007,
- 0x0002d006,
- 0x00f804bd,
-/* 0x0430: host_init */
- 0x008017f1,
- 0xf11014b6,
- 0xf1021815,
- 0xb604d007,
- 0x01d00604,
- 0xf104bd00,
- 0xb6008017,
- 0x15f11014,
- 0x07f10298,
- 0x04b604dc,
- 0x0001d006,
- 0x17f004bd,
- 0xc407f101,
- 0x0604b604,
- 0xbd0001d0,
-/* 0x046f: memx_func_enter */
- 0xf000f804,
- 0x07f10467,
- 0x04b607e0,
- 0x0006d006,
-/* 0x047e: memx_func_enter_wait */
- 0x67f104bd,
- 0x64b607c0,
- 0x0066cf06,
- 0xf40464f0,
- 0x1698f30b,
- 0x0410b600,
-/* 0x0496: memx_func_leave */
- 0x67f000f8,
- 0xe407f104,
- 0x0604b607,
- 0xbd0006d0,
-/* 0x04a5: memx_func_leave_wait */
- 0xc067f104,
- 0x0664b607,
- 0xf00066cf,
- 0x1bf40464,
-/* 0x04b7: memx_func_wr32 */
- 0x9800f8f3,
- 0x15980016,
- 0x0810b601,
- 0x50f960f9,
- 0xe0fcd0fc,
- 0xf13f21f4,
- 0xfd140003,
- 0x05800506,
- 0xb604bd00,
- 0x1bf40242,
-/* 0x04df: memx_func_wait */
- 0xf000f8dd,
- 0x84b62c87,
- 0x0088cf06,
- 0x98001e98,
- 0x1c98011d,
- 0x031b9802,
- 0xf41010b6,
- 0x00f89c21,
-/* 0x04fc: memx_func_delay */
- 0xb6001e98,
- 0x21f40410,
-/* 0x0507: memx_exec */
- 0xf900f87f,
- 0xb9d0f9e0,
- 0xb2b902c1,
-/* 0x0511: memx_exec_next */
- 0x00139802,
- 0x950410b6,
- 0x30f01034,
- 0xc835980c,
- 0x12b855f9,
- 0xec1ef406,
- 0xe0fcd0fc,
- 0x02b921f5,
-/* 0x0532: memx_info */
- 0xc7f100f8,
- 0xb7f10354,
- 0x21f50800,
- 0x00f802b9,
-/* 0x0540: memx_recv */
- 0xf401d6b0,
- 0xd6b0c40b,
- 0xe90bf400,
-/* 0x054e: memx_init */
- 0x00f800f8,
-/* 0x0550: perf_recv */
-/* 0x0552: perf_init */
- 0x00f800f8,
-/* 0x0554: test_recv */
- 0x05d817f1,
- 0xcf0614b6,
- 0x10b60011,
- 0xd807f101,
- 0x0604b605,
- 0xbd0001d0,
- 0x00e7f104,
- 0x4fe3f1d9,
- 0xf521f513,
-/* 0x057b: test_init */
- 0xf100f801,
- 0xf50800e7,
- 0xf801f521,
-/* 0x0585: idle_recv */
-/* 0x0587: idle */
- 0xf400f800,
- 0x17f10031,
- 0x14b605d4,
- 0x0011cf06,
- 0xf10110b6,
- 0xb605d407,
- 0x01d00604,
-/* 0x05a3: idle_loop */
- 0xf004bd00,
- 0x32f45817,
-/* 0x05a9: idle_proc */
-/* 0x05a9: idle_proc_exec */
- 0xb910f902,
- 0x21f5021e,
- 0x10fc02c2,
- 0xf40911f4,
- 0x0ef40231,
-/* 0x05bd: idle_proc_next */
- 0x5810b6ef,
- 0xf4061fb8,
- 0x02f4e61b,
- 0x0028f4dd,
- 0x00bb0ef4,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc
deleted file mode 100644
index eaa64da..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 NVKM_PPWR_CHIPSET GF100
-
-//#define NVKM_FALCON_PC24
-//#define NVKM_FALCON_UNSHIFTED_IO
-//#define NVKM_FALCON_MMIO_UAS
-//#define NVKM_FALCON_MMIO_TRAP
-
-#include "macros.fuc"
-
-.section #nvc0_pwr_data
-#define INCLUDE_PROC
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_PROC
-
-#define INCLUDE_DATA
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_DATA
-.align 256
-
-.section #nvc0_pwr_code
-#define INCLUDE_CODE
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_CODE
-.align 256
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
deleted file mode 100644
index 82c8e8b..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
+++ /dev/null
@@ -1,1229 +0,0 @@
-uint32_t nvc0_pwr_data[] = {
-/* 0x0000: proc_kern */
- 0x52544e49,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0058: proc_list_head */
- 0x54534f48,
- 0x00000430,
- 0x000003cd,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x584d454d,
- 0x0000054e,
- 0x00000540,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x46524550,
- 0x00000552,
- 0x00000550,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x54534554,
- 0x0000057b,
- 0x00000554,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x454c4449,
- 0x00000587,
- 0x00000585,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0210: proc_list_tail */
-/* 0x0210: time_prev */
- 0x00000000,
-/* 0x0214: time_next */
- 0x00000000,
-/* 0x0218: fifo_queue */
- 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,
-/* 0x0298: rfifo_queue */
- 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,
-/* 0x0318: memx_func_head */
- 0x00010000,
- 0x00000000,
- 0x0000046f,
-/* 0x0324: memx_func_next */
- 0x00000001,
- 0x00000000,
- 0x00000496,
- 0x00000002,
- 0x00000002,
- 0x000004b7,
- 0x00040003,
- 0x00000000,
- 0x000004df,
- 0x00010004,
- 0x00000000,
- 0x000004fc,
-/* 0x0354: memx_func_tail */
-/* 0x0354: memx_data_head */
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0b54: memx_data_tail */
- 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,
-};
-
-uint32_t nvc0_pwr_code[] = {
- 0x030d0ef5,
-/* 0x0004: rd32 */
- 0x07a007f1,
- 0xd00604b6,
- 0x04bd000e,
- 0xf001e7f0,
- 0x07f101e3,
- 0x04b607ac,
- 0x000ed006,
-/* 0x0022: rd32_wait */
- 0xe7f104bd,
- 0xe4b607ac,
- 0x00eecf06,
- 0x7000e4f1,
- 0xf1f21bf4,
- 0xb607a4d7,
- 0xddcf06d4,
-/* 0x003f: wr32 */
- 0xf100f800,
- 0xb607a007,
- 0x0ed00604,
- 0xf104bd00,
- 0xb607a407,
- 0x0dd00604,
- 0xf004bd00,
- 0xe5f002e7,
- 0x01e3f0f0,
- 0x07ac07f1,
- 0xd00604b6,
- 0x04bd000e,
-/* 0x006c: wr32_wait */
- 0x07ace7f1,
- 0xcf06e4b6,
- 0xe4f100ee,
- 0x1bf47000,
-/* 0x007f: nsec */
- 0xf000f8f2,
- 0x84b62c87,
- 0x0088cf06,
-/* 0x0088: nsec_loop */
- 0xb62c97f0,
- 0x99cf0694,
- 0x0298bb00,
- 0xf4069eb8,
- 0x00f8f11e,
-/* 0x009c: wait */
- 0xb62c87f0,
- 0x88cf0684,
-/* 0x00a5: wait_loop */
- 0x02eeb900,
- 0xb90421f4,
- 0xadfd02da,
- 0x06acb804,
- 0xf0150bf4,
- 0x94b62c97,
- 0x0099cf06,
- 0xb80298bb,
- 0x1ef4069b,
-/* 0x00c9: wait_done */
-/* 0x00cb: intr_watchdog */
- 0x9800f8df,
- 0x96b003e9,
- 0x2a0bf400,
- 0xbb840a98,
- 0x1cf4029a,
- 0x01d7f00f,
- 0x025421f5,
- 0x0ef494bd,
-/* 0x00e9: intr_watchdog_next_time */
- 0x850a9815,
- 0xf400a6b0,
- 0x9ab8090b,
- 0x061cf406,
-/* 0x00f8: intr_watchdog_next_time_set */
-/* 0x00fb: intr_watchdog_next_proc */
- 0x80850980,
- 0xe0b603e9,
- 0x10e6b158,
- 0xc61bf402,
-/* 0x010a: intr */
- 0x00f900f8,
- 0x80f904bd,
- 0xa0f990f9,
- 0xc0f9b0f9,
- 0xe0f9d0f9,
- 0xf7f0f0f9,
- 0x0188fe00,
- 0x87f180f9,
- 0x84b605d0,
- 0x0088cf06,
- 0xf10180b6,
- 0xb605d007,
- 0x08d00604,
- 0xf004bd00,
- 0x84b60887,
- 0x0088cf06,
- 0xf40289c4,
- 0x0080230b,
- 0x58e7f085,
- 0x98cb21f4,
- 0x96b08509,
- 0x110bf400,
- 0xb63407f0,
- 0x09d00604,
- 0x8004bd00,
-/* 0x016e: intr_skip_watchdog */
- 0x89e48409,
- 0x0bf40800,
- 0x8897f148,
- 0x0694b606,
- 0xc40099cf,
- 0x0bf4029a,
- 0xc0c7f12c,
- 0x06c4b604,
- 0xf900cccf,
- 0x48e7f1c0,
- 0x53e3f14f,
- 0x00d7f054,
- 0x02b921f5,
- 0x07f1c0fc,
- 0x04b604c0,
- 0x000cd006,
-/* 0x01ae: intr_subintr_skip_fifo */
- 0x07f104bd,
- 0x04b60688,
- 0x0009d006,
-/* 0x01ba: intr_skip_subintr */
- 0x89c404bd,
- 0x070bf420,
- 0xffbfa4f1,
-/* 0x01c4: intr_skip_pause */
- 0xf44089c4,
- 0xa4f1070b,
-/* 0x01ce: intr_skip_user0 */
- 0x07f0ffbf,
- 0x0604b604,
- 0xbd0008d0,
- 0xfe80fc04,
- 0xf0fc0088,
- 0xd0fce0fc,
- 0xb0fcc0fc,
- 0x90fca0fc,
- 0x00fc80fc,
- 0xf80032f4,
-/* 0x01f5: timer */
- 0x1032f401,
- 0xb003f898,
- 0x1cf40086,
- 0x03fe8051,
- 0xb63807f0,
- 0x08d00604,
- 0xf004bd00,
- 0x84b60887,
- 0x0088cf06,
- 0xf40284f0,
- 0x87f0261b,
- 0x0684b634,
- 0xb80088cf,
- 0x0bf406e0,
- 0x06e8b809,
-/* 0x0233: timer_reset */
- 0xf01f1ef4,
- 0x04b63407,
- 0x000ed006,
- 0x0e8004bd,
-/* 0x0241: timer_enable */
- 0x0187f084,
- 0xb63807f0,
- 0x08d00604,
-/* 0x024f: timer_done */
- 0xf404bd00,
- 0x00f81031,
-/* 0x0254: send_proc */
- 0x90f980f9,
- 0x9805e898,
- 0x86f004e9,
- 0x0689b804,
- 0xc42a0bf4,
- 0x88940398,
- 0x1880b604,
- 0x98008ebb,
- 0x8a8000fa,
- 0x018d8000,
- 0x80028c80,
- 0x90b6038b,
- 0x0794f001,
- 0xf404e980,
-/* 0x028e: send_done */
- 0x90fc0231,
- 0x00f880fc,
-/* 0x0294: find */
- 0x87f080f9,
- 0x0131f458,
-/* 0x029c: find_loop */
- 0xb8008a98,
- 0x0bf406ae,
- 0x5880b610,
- 0x021086b1,
- 0xf4f01bf4,
-/* 0x02b2: find_done */
- 0x8eb90132,
- 0xf880fc02,
-/* 0x02b9: send */
- 0x9421f500,
- 0x9701f402,
-/* 0x02c2: recv */
- 0xe89800f8,
- 0x04e99805,
- 0xb80132f4,
- 0x0bf40689,
- 0x0389c43d,
- 0xf00180b6,
- 0xe8800784,
- 0x02ea9805,
- 0x8ffef0f9,
- 0xb9f0f901,
- 0x999402ef,
- 0x00e9bb04,
- 0x9818e0b6,
- 0xec9803eb,
- 0x01ed9802,
- 0xf900ee98,
- 0xfef0fca5,
- 0x31f400f8,
-/* 0x030b: recv_done */
- 0xf8f0fc01,
-/* 0x030d: init */
- 0x0817f100,
- 0x0614b601,
- 0xe70011cf,
- 0xb6010911,
- 0x14fe0814,
- 0xe017f100,
- 0x0013f000,
- 0xb61c07f0,
- 0x01d00604,
- 0xf004bd00,
- 0x07f0ff17,
- 0x0604b614,
- 0xbd0001d0,
- 0x0217f004,
- 0x080015f1,
- 0xb61007f0,
- 0x01d00604,
- 0xf104bd00,
- 0xf0010a17,
- 0x10fe0013,
- 0x1031f400,
- 0xf00117f0,
- 0x04b63807,
- 0x0001d006,
- 0xf7f004bd,
-/* 0x0371: init_proc */
- 0x01f19858,
- 0xf40016b0,
- 0x15f9fa0b,
- 0xf458f0b6,
-/* 0x0382: host_send */
- 0x17f1f20e,
- 0x14b604b0,
- 0x0011cf06,
- 0x04a027f1,
- 0xcf0624b6,
- 0x12b80022,
- 0x320bf406,
- 0x94071ec4,
- 0xe0b704ee,
- 0xeb980218,
- 0x02ec9803,
- 0x9801ed98,
- 0x21f500ee,
- 0x10b602b9,
- 0x0f1ec401,
- 0x04b007f1,
- 0xd00604b6,
- 0x04bd0001,
-/* 0x03cb: host_send_done */
- 0xf8ba0ef4,
-/* 0x03cd: host_recv */
- 0x4917f100,
- 0x5413f14e,
- 0x06e1b852,
-/* 0x03db: host_recv_wait */
- 0xf1aa0bf4,
- 0xb604cc17,
- 0x11cf0614,
- 0xc827f100,
- 0x0624b604,
- 0xf00022cf,
- 0x12b80816,
- 0xe60bf406,
- 0xb60723c4,
- 0x30b70434,
- 0x3b800298,
- 0x023c8003,
- 0x80013d80,
- 0x20b6003e,
- 0x0f24f001,
- 0x04c807f1,
- 0xd00604b6,
- 0x04bd0002,
- 0xf04027f0,
- 0x04b60007,
- 0x0002d006,
- 0x00f804bd,
-/* 0x0430: host_init */
- 0x008017f1,
- 0xf11014b6,
- 0xf1021815,
- 0xb604d007,
- 0x01d00604,
- 0xf104bd00,
- 0xb6008017,
- 0x15f11014,
- 0x07f10298,
- 0x04b604dc,
- 0x0001d006,
- 0x17f004bd,
- 0xc407f101,
- 0x0604b604,
- 0xbd0001d0,
-/* 0x046f: memx_func_enter */
- 0xf000f804,
- 0x07f10467,
- 0x04b607e0,
- 0x0006d006,
-/* 0x047e: memx_func_enter_wait */
- 0x67f104bd,
- 0x64b607c0,
- 0x0066cf06,
- 0xf40464f0,
- 0x1698f30b,
- 0x0410b600,
-/* 0x0496: memx_func_leave */
- 0x67f000f8,
- 0xe407f104,
- 0x0604b607,
- 0xbd0006d0,
-/* 0x04a5: memx_func_leave_wait */
- 0xc067f104,
- 0x0664b607,
- 0xf00066cf,
- 0x1bf40464,
-/* 0x04b7: memx_func_wr32 */
- 0x9800f8f3,
- 0x15980016,
- 0x0810b601,
- 0x50f960f9,
- 0xe0fcd0fc,
- 0xf13f21f4,
- 0xfd140003,
- 0x05800506,
- 0xb604bd00,
- 0x1bf40242,
-/* 0x04df: memx_func_wait */
- 0xf000f8dd,
- 0x84b62c87,
- 0x0088cf06,
- 0x98001e98,
- 0x1c98011d,
- 0x031b9802,
- 0xf41010b6,
- 0x00f89c21,
-/* 0x04fc: memx_func_delay */
- 0xb6001e98,
- 0x21f40410,
-/* 0x0507: memx_exec */
- 0xf900f87f,
- 0xb9d0f9e0,
- 0xb2b902c1,
-/* 0x0511: memx_exec_next */
- 0x00139802,
- 0x950410b6,
- 0x30f01034,
- 0xc835980c,
- 0x12b855f9,
- 0xec1ef406,
- 0xe0fcd0fc,
- 0x02b921f5,
-/* 0x0532: memx_info */
- 0xc7f100f8,
- 0xb7f10354,
- 0x21f50800,
- 0x00f802b9,
-/* 0x0540: memx_recv */
- 0xf401d6b0,
- 0xd6b0c40b,
- 0xe90bf400,
-/* 0x054e: memx_init */
- 0x00f800f8,
-/* 0x0550: perf_recv */
-/* 0x0552: perf_init */
- 0x00f800f8,
-/* 0x0554: test_recv */
- 0x05d817f1,
- 0xcf0614b6,
- 0x10b60011,
- 0xd807f101,
- 0x0604b605,
- 0xbd0001d0,
- 0x00e7f104,
- 0x4fe3f1d9,
- 0xf521f513,
-/* 0x057b: test_init */
- 0xf100f801,
- 0xf50800e7,
- 0xf801f521,
-/* 0x0585: idle_recv */
-/* 0x0587: idle */
- 0xf400f800,
- 0x17f10031,
- 0x14b605d4,
- 0x0011cf06,
- 0xf10110b6,
- 0xb605d407,
- 0x01d00604,
-/* 0x05a3: idle_loop */
- 0xf004bd00,
- 0x32f45817,
-/* 0x05a9: idle_proc */
-/* 0x05a9: idle_proc_exec */
- 0xb910f902,
- 0x21f5021e,
- 0x10fc02c2,
- 0xf40911f4,
- 0x0ef40231,
-/* 0x05bd: idle_proc_next */
- 0x5810b6ef,
- 0xf4061fb8,
- 0x02f4e61b,
- 0x0028f4dd,
- 0x00bb0ef4,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc
deleted file mode 100644
index 32d65ea..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 NVKM_PPWR_CHIPSET GF119
-
-//#define NVKM_FALCON_PC24
-#define NVKM_FALCON_UNSHIFTED_IO
-//#define NVKM_FALCON_MMIO_UAS
-//#define NVKM_FALCON_MMIO_TRAP
-
-#include "macros.fuc"
-
-.section #nvd0_pwr_data
-#define INCLUDE_PROC
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_PROC
-
-#define INCLUDE_DATA
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_DATA
-.align 256
-
-.section #nvd0_pwr_code
-#define INCLUDE_CODE
-#include "kernel.fuc"
-#include "host.fuc"
-#include "memx.fuc"
-#include "perf.fuc"
-#include "test.fuc"
-#include "idle.fuc"
-#undef INCLUDE_CODE
-.align 256
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
deleted file mode 100644
index ce65e2a..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
+++ /dev/null
@@ -1,1229 +0,0 @@
-uint32_t nvd0_pwr_data[] = {
-/* 0x0000: proc_kern */
- 0x52544e49,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0058: proc_list_head */
- 0x54534f48,
- 0x000003be,
- 0x00000367,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x584d454d,
- 0x000004c4,
- 0x000004b6,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x46524550,
- 0x000004c8,
- 0x000004c6,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x54534554,
- 0x000004eb,
- 0x000004ca,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x454c4449,
- 0x000004f7,
- 0x000004f5,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0210: proc_list_tail */
-/* 0x0210: time_prev */
- 0x00000000,
-/* 0x0214: time_next */
- 0x00000000,
-/* 0x0218: fifo_queue */
- 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,
-/* 0x0298: rfifo_queue */
- 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,
-/* 0x0318: memx_func_head */
- 0x00010000,
- 0x00000000,
- 0x000003f4,
-/* 0x0324: memx_func_next */
- 0x00000001,
- 0x00000000,
- 0x00000415,
- 0x00000002,
- 0x00000002,
- 0x00000430,
- 0x00040003,
- 0x00000000,
- 0x00000458,
- 0x00010004,
- 0x00000000,
- 0x00000472,
-/* 0x0354: memx_func_tail */
-/* 0x0354: memx_data_head */
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
-/* 0x0b54: memx_data_tail */
- 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,
-};
-
-uint32_t nvd0_pwr_code[] = {
- 0x02bf0ef5,
-/* 0x0004: rd32 */
- 0x07a007f1,
- 0xbd000ed0,
- 0x01e7f004,
- 0xf101e3f0,
- 0xd007ac07,
- 0x04bd000e,
-/* 0x001c: rd32_wait */
- 0x07ace7f1,
- 0xf100eecf,
- 0xf47000e4,
- 0xd7f1f51b,
- 0xddcf07a4,
-/* 0x0033: wr32 */
- 0xf100f800,
- 0xd007a007,
- 0x04bd000e,
- 0x07a407f1,
- 0xbd000dd0,
- 0x02e7f004,
- 0xf0f0e5f0,
- 0x07f101e3,
- 0x0ed007ac,
-/* 0x0057: wr32_wait */
- 0xf104bd00,
- 0xcf07ace7,
- 0xe4f100ee,
- 0x1bf47000,
-/* 0x0067: nsec */
- 0xf000f8f5,
- 0x88cf2c87,
-/* 0x006d: nsec_loop */
- 0x2c97f000,
- 0xbb0099cf,
- 0x9eb80298,
- 0xf41ef406,
-/* 0x007e: wait */
- 0x87f000f8,
- 0x0088cf2c,
-/* 0x0084: wait_loop */
- 0xf402eeb9,
- 0xdab90421,
- 0x04adfd02,
- 0xf406acb8,
- 0x97f0120b,
- 0x0099cf2c,
- 0xb80298bb,
- 0x1ef4069b,
-/* 0x00a5: wait_done */
-/* 0x00a7: intr_watchdog */
- 0x9800f8e2,
- 0x96b003e9,
- 0x2a0bf400,
- 0xbb840a98,
- 0x1cf4029a,
- 0x01d7f00f,
- 0x020621f5,
- 0x0ef494bd,
-/* 0x00c5: intr_watchdog_next_time */
- 0x850a9815,
- 0xf400a6b0,
- 0x9ab8090b,
- 0x061cf406,
-/* 0x00d4: intr_watchdog_next_time_set */
-/* 0x00d7: intr_watchdog_next_proc */
- 0x80850980,
- 0xe0b603e9,
- 0x10e6b158,
- 0xc61bf402,
-/* 0x00e6: intr */
- 0x00f900f8,
- 0x80f904bd,
- 0xa0f990f9,
- 0xc0f9b0f9,
- 0xe0f9d0f9,
- 0xf7f0f0f9,
- 0x0188fe00,
- 0x87f180f9,
- 0x88cf05d0,
- 0x0180b600,
- 0x05d007f1,
- 0xbd0008d0,
- 0x0887f004,
- 0xc40088cf,
- 0x0bf40289,
- 0x85008020,
- 0xf458e7f0,
- 0x0998a721,
- 0x0096b085,
- 0xf00e0bf4,
- 0x09d03407,
- 0x8004bd00,
-/* 0x013e: intr_skip_watchdog */
- 0x89e48409,
- 0x0bf40800,
- 0x8897f13c,
- 0x0099cf06,
- 0xf4029ac4,
- 0xc7f1260b,
- 0xcccf04c0,
- 0xf1c0f900,
- 0xf14f48e7,
- 0xf05453e3,
- 0x21f500d7,
- 0xc0fc026b,
- 0x04c007f1,
- 0xbd000cd0,
-/* 0x0175: intr_subintr_skip_fifo */
- 0x8807f104,
- 0x0009d006,
-/* 0x017e: intr_skip_subintr */
- 0x89c404bd,
- 0x070bf420,
- 0xffbfa4f1,
-/* 0x0188: intr_skip_pause */
- 0xf44089c4,
- 0xa4f1070b,
-/* 0x0192: intr_skip_user0 */
- 0x07f0ffbf,
- 0x0008d004,
- 0x80fc04bd,
- 0xfc0088fe,
- 0xfce0fcf0,
- 0xfcc0fcd0,
- 0xfca0fcb0,
- 0xfc80fc90,
- 0x0032f400,
-/* 0x01b6: timer */
- 0x32f401f8,
- 0x03f89810,
- 0xf40086b0,
- 0xfe80421c,
- 0x3807f003,
- 0xbd0008d0,
- 0x0887f004,
- 0xf00088cf,
- 0x1bf40284,
- 0x3487f020,
- 0xb80088cf,
- 0x0bf406e0,
- 0x06e8b809,
-/* 0x01eb: timer_reset */
- 0xf0191ef4,
- 0x0ed03407,
- 0x8004bd00,
-/* 0x01f6: timer_enable */
- 0x87f0840e,
- 0x3807f001,
- 0xbd0008d0,
-/* 0x0201: timer_done */
- 0x1031f404,
-/* 0x0206: send_proc */
- 0x80f900f8,
- 0xe89890f9,
- 0x04e99805,
- 0xb80486f0,
- 0x0bf40689,
- 0x0398c42a,
- 0xb6048894,
- 0x8ebb1880,
- 0x00fa9800,
- 0x80008a80,
- 0x8c80018d,
- 0x038b8002,
- 0xf00190b6,
- 0xe9800794,
- 0x0231f404,
-/* 0x0240: send_done */
- 0x80fc90fc,
-/* 0x0246: find */
- 0x80f900f8,
- 0xf45887f0,
-/* 0x024e: find_loop */
- 0x8a980131,
- 0x06aeb800,
- 0xb6100bf4,
- 0x86b15880,
- 0x1bf40210,
- 0x0132f4f0,
-/* 0x0264: find_done */
- 0xfc028eb9,
-/* 0x026b: send */
- 0xf500f880,
- 0xf4024621,
- 0x00f89701,
-/* 0x0274: recv */
- 0x9805e898,
- 0x32f404e9,
- 0x0689b801,
- 0xc43d0bf4,
- 0x80b60389,
- 0x0784f001,
- 0x9805e880,
- 0xf0f902ea,
- 0xf9018ffe,
- 0x02efb9f0,
- 0xbb049994,
- 0xe0b600e9,
- 0x03eb9818,
- 0x9802ec98,
- 0xee9801ed,
- 0xfca5f900,
- 0x00f8fef0,
- 0xfc0131f4,
-/* 0x02bd: recv_done */
-/* 0x02bf: init */
- 0xf100f8f0,
- 0xcf010817,
- 0x11e70011,
- 0x14b60109,
- 0x0014fe08,
- 0x00e017f1,
- 0xf00013f0,
- 0x01d01c07,
- 0xf004bd00,
- 0x07f0ff17,
- 0x0001d014,
- 0x17f004bd,
- 0x0015f102,
- 0x1007f008,
- 0xbd0001d0,
- 0xe617f104,
- 0x0013f000,
- 0xf40010fe,
- 0x17f01031,
- 0x3807f001,
- 0xbd0001d0,
- 0x58f7f004,
-/* 0x0314: init_proc */
- 0xb001f198,
- 0x0bf40016,
- 0xb615f9fa,
- 0x0ef458f0,
-/* 0x0325: host_send */
- 0xb017f1f2,
- 0x0011cf04,
- 0x04a027f1,
- 0xb80022cf,
- 0x0bf40612,
- 0x071ec42f,
- 0xb704ee94,
- 0x980218e0,
- 0xec9803eb,
- 0x01ed9802,
- 0xf500ee98,
- 0xb6026b21,
- 0x1ec40110,
- 0xb007f10f,
- 0x0001d004,
- 0x0ef404bd,
-/* 0x0365: host_send_done */
-/* 0x0367: host_recv */
- 0xf100f8c3,
- 0xf14e4917,
- 0xb8525413,
- 0x0bf406e1,
-/* 0x0375: host_recv_wait */
- 0xcc17f1b3,
- 0x0011cf04,
- 0x04c827f1,
- 0xf00022cf,
- 0x12b80816,
- 0xec0bf406,
- 0xb60723c4,
- 0x30b70434,
- 0x3b800298,
- 0x023c8003,
- 0x80013d80,
- 0x20b6003e,
- 0x0f24f001,
- 0x04c807f1,
- 0xbd0002d0,
- 0x4027f004,
- 0xd00007f0,
- 0x04bd0002,
-/* 0x03be: host_init */
- 0x17f100f8,
- 0x14b60080,
- 0x1815f110,
- 0xd007f102,
- 0x0001d004,
- 0x17f104bd,
- 0x14b60080,
- 0x9815f110,
- 0xdc07f102,
- 0x0001d004,
- 0x17f004bd,
- 0xc407f101,
- 0x0001d004,
- 0x00f804bd,
-/* 0x03f4: memx_func_enter */
- 0xf10467f0,
- 0xd007e007,
- 0x04bd0006,
-/* 0x0400: memx_func_enter_wait */
- 0x07c067f1,
- 0xf00066cf,
- 0x0bf40464,
- 0x001698f6,
- 0xf80410b6,
-/* 0x0415: memx_func_leave */
- 0x0467f000,
- 0x07e407f1,
- 0xbd0006d0,
-/* 0x0421: memx_func_leave_wait */
- 0xc067f104,
- 0x0066cf07,
- 0xf40464f0,
- 0x00f8f61b,
-/* 0x0430: memx_func_wr32 */
- 0x98001698,
- 0x10b60115,
- 0xf960f908,
- 0xfcd0fc50,
- 0x3321f4e0,
- 0x140003f1,
- 0x800506fd,
- 0x04bd0005,
- 0xf40242b6,
- 0x00f8dd1b,
-/* 0x0458: memx_func_wait */
- 0xcf2c87f0,
- 0x1e980088,
- 0x011d9800,
- 0x98021c98,
- 0x10b6031b,
- 0x7e21f410,
-/* 0x0472: memx_func_delay */
- 0x1e9800f8,
- 0x0410b600,
- 0xf86721f4,
-/* 0x047d: memx_exec */
- 0xf9e0f900,
- 0x02c1b9d0,
-/* 0x0487: memx_exec_next */
- 0x9802b2b9,
- 0x10b60013,
- 0x10349504,
- 0x980c30f0,
- 0x55f9c835,
- 0xf40612b8,
- 0xd0fcec1e,
- 0x21f5e0fc,
- 0x00f8026b,
-/* 0x04a8: memx_info */
- 0x0354c7f1,
- 0x0800b7f1,
- 0x026b21f5,
-/* 0x04b6: memx_recv */
- 0xd6b000f8,
- 0xc40bf401,
- 0xf400d6b0,
- 0x00f8e90b,
-/* 0x04c4: memx_init */
-/* 0x04c6: perf_recv */
- 0x00f800f8,
-/* 0x04c8: perf_init */
-/* 0x04ca: test_recv */
- 0x17f100f8,
- 0x11cf05d8,
- 0x0110b600,
- 0x05d807f1,
- 0xbd0001d0,
- 0x00e7f104,
- 0x4fe3f1d9,
- 0xb621f513,
-/* 0x04eb: test_init */
- 0xf100f801,
- 0xf50800e7,
- 0xf801b621,
-/* 0x04f5: idle_recv */
-/* 0x04f7: idle */
- 0xf400f800,
- 0x17f10031,
- 0x11cf05d4,
- 0x0110b600,
- 0x05d407f1,
- 0xbd0001d0,
-/* 0x050d: idle_loop */
- 0x5817f004,
-/* 0x0513: idle_proc */
-/* 0x0513: idle_proc_exec */
- 0xf90232f4,
- 0x021eb910,
- 0x027421f5,
- 0x11f410fc,
- 0x0231f409,
-/* 0x0527: idle_proc_next */
- 0xb6ef0ef4,
- 0x1fb85810,
- 0xe61bf406,
- 0xf4dd02f4,
- 0x0ef40028,
- 0x000000c1,
- 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,
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
deleted file mode 100644
index 5fb0ccc..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __NVKM_PWR_OS_H__
-#define __NVKM_PWR_OS_H__
-
-/* Process names */
-#define PROC_KERN 0x52544e49
-#define PROC_IDLE 0x454c4449
-#define PROC_HOST 0x54534f48
-#define PROC_MEMX 0x584d454d
-#define PROC_PERF 0x46524550
-#define PROC_TEST 0x54534554
-
-/* KERN: message identifiers */
-#define KMSG_FIFO 0x00000000
-#define KMSG_ALARM 0x00000001
-
-/* MEMX: message identifiers */
-#define MEMX_MSG_INFO 0
-#define MEMX_MSG_EXEC 1
-
-/* MEMX: script opcode definitions */
-#define MEMX_ENTER 0
-#define MEMX_LEAVE 1
-#define MEMX_WR32 2
-#define MEMX_WAIT 3
-#define MEMX_DELAY 4
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc
deleted file mode 100644
index 38eadf7..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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
- */
-
-#ifdef INCLUDE_PROC
-process(PROC_PERF, #perf_init, #perf_recv)
-#endif
-
-/******************************************************************************
- * PERF data segment
- *****************************************************************************/
-#ifdef INCLUDE_DATA
-#endif
-
-/******************************************************************************
- * PERF code segment
- *****************************************************************************/
-#ifdef INCLUDE_CODE
-
-// description
-//
-// $r15 - current (perf)
-// $r14 - sender process name
-// $r13 - message
-// $r12 - data0
-// $r11 - data1
-// $r0 - zero
-perf_recv:
- ret
-
-// description
-//
-// $r15 - current (perf)
-// $r0 - zero
-perf_init:
- ret
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc
deleted file mode 100644
index 0c3a71b..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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
- */
-
-#ifdef INCLUDE_PROC
-process(PROC_TEST, #test_init, #test_recv)
-#endif
-
-/******************************************************************************
- * TEST data segment
- *****************************************************************************/
-#ifdef INCLUDE_DATA
-#endif
-
-/******************************************************************************
- * TEST code segment
- *****************************************************************************/
-#ifdef INCLUDE_CODE
-// description
-//
-// $r15 - current (test)
-// $r14 - sender process name
-// $r13 - message
-// $r12 - data0
-// $r11 - data1
-// $r0 - zero
-test_recv:
- nv_iord($r1, NV_PPWR_DSCRATCH(2))
- add b32 $r1 1
- nv_iowr(NV_PPWR_DSCRATCH(2), $r1)
- mov $r14 -0x2700 /* 0xd900, envyas grrr! */
- sethi $r14 0x134f0000
- call(timer)
- ret
-
-// description
-//
-// $r15 - current (test)
-// $r0 - zero
-test_init:
- mov $r14 0x800
- call(timer)
- ret
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
deleted file mode 100644
index 03de310..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#ifndef __NVKM_PWR_MEMX_H__
-#define __NVKM_PWR_MEMX_H__
-
-#include <subdev/pwr.h>
-#include <subdev/pwr/fuc/os.h>
-
-struct nouveau_memx {
- struct nouveau_pwr *ppwr;
- u32 base;
- u32 size;
- struct {
- u32 mthd;
- u32 size;
- u32 data[64];
- } c;
-};
-
-static void
-memx_out(struct nouveau_memx *memx)
-{
- struct nouveau_pwr *ppwr = memx->ppwr;
- int i;
-
- if (memx->c.size) {
- nv_wr32(ppwr, 0x10a1c4, (memx->c.size << 16) | memx->c.mthd);
- for (i = 0; i < memx->c.size; i++)
- nv_wr32(ppwr, 0x10a1c4, memx->c.data[i]);
- memx->c.size = 0;
- }
-}
-
-static void
-memx_cmd(struct nouveau_memx *memx, u32 mthd, u32 size, u32 data[])
-{
- if ((memx->c.size + size >= ARRAY_SIZE(memx->c.data)) ||
- (memx->c.size && memx->c.mthd != mthd))
- memx_out(memx);
- memcpy(&memx->c.data[memx->c.size], data, size * sizeof(data[0]));
- memx->c.size += size;
- memx->c.mthd = mthd;
-}
-
-int
-nouveau_memx_init(struct nouveau_pwr *ppwr, struct nouveau_memx **pmemx)
-{
- struct nouveau_memx *memx;
- u32 reply[2];
- int ret;
-
- ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO, 0, 0);
- if (ret)
- return ret;
-
- memx = *pmemx = kzalloc(sizeof(*memx), GFP_KERNEL);
- if (!memx)
- return -ENOMEM;
- memx->ppwr = ppwr;
- memx->base = reply[0];
- memx->size = reply[1];
-
- /* acquire data segment access */
- do {
- nv_wr32(ppwr, 0x10a580, 0x00000003);
- } while (nv_rd32(ppwr, 0x10a580) != 0x00000003);
- nv_wr32(ppwr, 0x10a1c0, 0x01000000 | memx->base);
- nv_wr32(ppwr, 0x10a1c4, 0x00010000 | MEMX_ENTER);
- nv_wr32(ppwr, 0x10a1c4, 0x00000000);
- return 0;
-}
-
-int
-nouveau_memx_fini(struct nouveau_memx **pmemx, bool exec)
-{
- struct nouveau_memx *memx = *pmemx;
- struct nouveau_pwr *ppwr = memx->ppwr;
- u32 finish, reply[2];
-
- /* flush the cache... */
- memx_out(memx);
-
- /* release data segment access */
- nv_wr32(ppwr, 0x10a1c4, 0x00000000 | MEMX_LEAVE);
- finish = nv_rd32(ppwr, 0x10a1c0) & 0x00ffffff;
- nv_wr32(ppwr, 0x10a580, 0x00000000);
-
- /* call MEMX process to execute the script, and wait for reply */
- if (exec) {
- ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_EXEC,
- memx->base, finish);
- }
-
- kfree(memx);
- return 0;
-}
-
-void
-nouveau_memx_wr32(struct nouveau_memx *memx, u32 addr, u32 data)
-{
- nv_debug(memx->ppwr, "R[%06x] = 0x%08x\n", addr, data);
- memx_cmd(memx, MEMX_WR32, 2, (u32[]){ addr, data });
-}
-
-void
-nouveau_memx_wait(struct nouveau_memx *memx,
- u32 addr, u32 mask, u32 data, u32 nsec)
-{
- nv_debug(memx->ppwr, "R[%06x] & 0x%08x == 0x%08x, %d us\n",
- addr, mask, data, nsec);
- memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, ~mask, data, nsec });
- memx_out(memx); /* fuc can't handle multiple */
-}
-
-void
-nouveau_memx_nsec(struct nouveau_memx *memx, u32 nsec)
-{
- nv_debug(memx->ppwr, " DELAY = %d ns\n", nsec);
- memx_cmd(memx, MEMX_DELAY, 1, (u32[]){ nsec });
- memx_out(memx); /* fuc can't handle multiple */
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c
deleted file mode 100644
index 52c8541..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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/pwr.h>
-
-#include "fuc/nv108.fuc.h"
-
-struct nv108_pwr_priv {
- struct nouveau_pwr base;
-};
-
-static int
-nv108_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv108_pwr_priv *priv;
- int ret;
-
- ret = nouveau_pwr_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.code.data = nv108_pwr_code;
- priv->base.code.size = sizeof(nv108_pwr_code);
- priv->base.data.data = nv108_pwr_data;
- priv->base.data.size = sizeof(nv108_pwr_data);
- return 0;
-}
-
-struct nouveau_oclass
-nv108_pwr_oclass = {
- .handle = NV_SUBDEV(PWR, 0x00),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv108_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = _nouveau_pwr_init,
- .fini = _nouveau_pwr_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c
deleted file mode 100644
index c132b7c..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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/pwr.h>
-
-#include "fuc/nva3.fuc.h"
-
-struct nva3_pwr_priv {
- struct nouveau_pwr base;
-};
-
-static int
-nva3_pwr_init(struct nouveau_object *object)
-{
- struct nva3_pwr_priv *priv = (void *)object;
- nv_mask(priv, 0x022210, 0x00000001, 0x00000000);
- nv_mask(priv, 0x022210, 0x00000001, 0x00000001);
- return nouveau_pwr_init(&priv->base);
-}
-
-static int
-nva3_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nva3_pwr_priv *priv;
- int ret;
-
- ret = nouveau_pwr_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.code.data = nva3_pwr_code;
- priv->base.code.size = sizeof(nva3_pwr_code);
- priv->base.data.data = nva3_pwr_data;
- priv->base.data.size = sizeof(nva3_pwr_data);
- return 0;
-}
-
-struct nouveau_oclass
-nva3_pwr_oclass = {
- .handle = NV_SUBDEV(PWR, 0xa3),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = nva3_pwr_init,
- .fini = _nouveau_pwr_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c
deleted file mode 100644
index 495f685..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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/pwr.h>
-
-#include "fuc/nvc0.fuc.h"
-
-struct nvc0_pwr_priv {
- struct nouveau_pwr base;
-};
-
-static int
-nvc0_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_pwr_priv *priv;
- int ret;
-
- ret = nouveau_pwr_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.code.data = nvc0_pwr_code;
- priv->base.code.size = sizeof(nvc0_pwr_code);
- priv->base.data.data = nvc0_pwr_data;
- priv->base.data.size = sizeof(nvc0_pwr_data);
- return 0;
-}
-
-struct nouveau_oclass
-nvc0_pwr_oclass = {
- .handle = NV_SUBDEV(PWR, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = _nouveau_pwr_init,
- .fini = _nouveau_pwr_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c
deleted file mode 100644
index 043aa14..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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/pwr.h>
-
-#include "fuc/nvd0.fuc.h"
-
-struct nvd0_pwr_priv {
- struct nouveau_pwr base;
-};
-
-static int
-nvd0_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvd0_pwr_priv *priv;
- int ret;
-
- ret = nouveau_pwr_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.code.data = nvd0_pwr_code;
- priv->base.code.size = sizeof(nvd0_pwr_code);
- priv->base.data.data = nvd0_pwr_data;
- priv->base.data.size = sizeof(nvd0_pwr_data);
- return 0;
-}
-
-struct nouveau_oclass
-nvd0_pwr_oclass = {
- .handle = NV_SUBDEV(PWR, 0xd0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvd0_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = _nouveau_pwr_init,
- .fini = _nouveau_pwr_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
index 80e584a..f1de7a9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
@@ -92,11 +92,10 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
struct nouveau_timer *ptimer = nouveau_timer(therm);
struct nouveau_therm_priv *priv = (void *)therm;
unsigned long flags;
- bool immd = true;
- bool poll = true;
- int duty = -1;
+ int duty;
spin_lock_irqsave(&priv->lock, flags);
+ nv_debug(therm, "FAN speed check\n");
if (mode < 0)
mode = priv->mode;
priv->mode = mode;
@@ -107,49 +106,28 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
duty = nouveau_therm_fan_get(therm);
if (duty < 0)
duty = 100;
- poll = false;
break;
case NOUVEAU_THERM_CTRL_AUTO:
- if (priv->fan->bios.nr_fan_trip) {
+ if (priv->fan->bios.nr_fan_trip)
duty = nouveau_therm_update_trip(therm);
- } else
- if (priv->fan->bios.linear_min_temp ||
- priv->fan->bios.linear_max_temp) {
+ else
duty = nouveau_therm_update_linear(therm);
- } else {
- if (priv->cstate)
- duty = priv->cstate;
- poll = false;
- }
- immd = false;
break;
case NOUVEAU_THERM_CTRL_NONE:
default:
ptimer->alarm_cancel(ptimer, &priv->alarm);
- poll = false;
+ goto done;
}
- if (list_empty(&priv->alarm.head) && poll)
+ nv_debug(therm, "FAN target request: %d%%\n", duty);
+ nouveau_therm_fan_set(therm, (mode != NOUVEAU_THERM_CTRL_AUTO), duty);
+
+done:
+ if (list_empty(&priv->alarm.head) && (mode == NOUVEAU_THERM_CTRL_AUTO))
ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm);
+ else if (!list_empty(&priv->alarm.head))
+ nv_debug(therm, "therm fan alarm list is not empty\n");
spin_unlock_irqrestore(&priv->lock, flags);
-
- if (duty >= 0) {
- nv_debug(therm, "FAN target request: %d%%\n", duty);
- nouveau_therm_fan_set(therm, immd, duty);
- }
-}
-
-int
-nouveau_therm_cstate(struct nouveau_therm *ptherm, int fan, int dir)
-{
- struct nouveau_therm_priv *priv = (void *)ptherm;
- if (!dir || (dir < 0 && fan < priv->cstate) ||
- (dir > 0 && fan > priv->cstate)) {
- nv_debug(ptherm, "default fan speed -> %d%%\n", fan);
- priv->cstate = fan;
- nouveau_therm_update(ptherm, -1);
- }
- return 0;
}
static void
@@ -171,15 +149,14 @@ nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode)
"automatic"
};
- /* The default PPWR ucode on fermi interferes with fan management */
+ /* The default PDAEMON ucode interferes with fan management */
if ((mode >= ARRAY_SIZE(name)) ||
- (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0 &&
- !nouveau_subdev(device, NVDEV_SUBDEV_PWR)))
+ (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0))
return -EINVAL;
/* do not allow automatic fan management if the thermal sensor is
* not available */
- if (priv->mode == NOUVEAU_THERM_CTRL_AUTO && therm->temp_get(therm) < 0)
+ if (priv->mode == 2 && therm->temp_get(therm) < 0)
return -EINVAL;
if (priv->mode == mode)
@@ -358,7 +335,7 @@ nouveau_therm_preinit(struct nouveau_therm *therm)
nouveau_therm_ic_ctor(therm);
nouveau_therm_fan_ctor(therm);
- nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
+ nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE);
nouveau_therm_sensor_preinit(therm);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
index 95f6129..39f47b9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
@@ -185,11 +185,8 @@ nouveau_therm_fan_set_defaults(struct nouveau_therm *therm)
priv->fan->bios.max_duty = 100;
priv->fan->bios.bump_period = 500;
priv->fan->bios.slow_down_period = 2000;
-/*XXX: talk to mupuf */
-#if 0
priv->fan->bios.linear_min_temp = 40;
priv->fan->bios.linear_max_temp = 85;
-#endif
}
static void
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c
index f69dab1..e601773 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c
@@ -97,13 +97,6 @@ nouveau_fantog_create(struct nouveau_therm *therm, struct dcb_gpio_func *func)
{
struct nouveau_therm_priv *tpriv = (void *)therm;
struct nouveau_fantog_priv *priv;
- int ret;
-
- if (therm->pwm_ctrl) {
- ret = therm->pwm_ctrl(therm, func->line, false);
- if (ret)
- return ret;
- }
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
tpriv->fan = &priv->base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
index e44ed7b..8b3adec 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
@@ -41,8 +41,7 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c,
if (!client)
return false;
- if (!client->dev.driver ||
- to_i2c_driver(client->dev.driver)->detect(client, info)) {
+ if (!client->driver || client->driver->detect(client, info)) {
i2c_unregister_device(client);
return false;
}
@@ -56,28 +55,28 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c,
return true;
}
-static struct nouveau_i2c_board_info
+static struct i2c_board_info
nv_board_infos[] = {
- { { I2C_BOARD_INFO("w83l785ts", 0x2d) }, 0 },
- { { I2C_BOARD_INFO("w83781d", 0x2d) }, 0 },
- { { I2C_BOARD_INFO("adt7473", 0x2e) }, 20 },
- { { I2C_BOARD_INFO("adt7473", 0x2d) }, 20 },
- { { I2C_BOARD_INFO("adt7473", 0x2c) }, 20 },
- { { I2C_BOARD_INFO("f75375", 0x2e) }, 0 },
- { { I2C_BOARD_INFO("lm99", 0x4c) }, 0 },
- { { I2C_BOARD_INFO("lm90", 0x4c) }, 0 },
- { { I2C_BOARD_INFO("lm90", 0x4d) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x18) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x19) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x1a) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x29) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x2a) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x2b) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x4c) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x4d) }, 0 },
- { { I2C_BOARD_INFO("adm1021", 0x4e) }, 0 },
- { { I2C_BOARD_INFO("lm63", 0x18) }, 0 },
- { { I2C_BOARD_INFO("lm63", 0x4e) }, 0 },
+ { I2C_BOARD_INFO("w83l785ts", 0x2d) },
+ { I2C_BOARD_INFO("w83781d", 0x2d) },
+ { I2C_BOARD_INFO("adt7473", 0x2e) },
+ { I2C_BOARD_INFO("adt7473", 0x2d) },
+ { I2C_BOARD_INFO("adt7473", 0x2c) },
+ { I2C_BOARD_INFO("f75375", 0x2e) },
+ { I2C_BOARD_INFO("lm99", 0x4c) },
+ { I2C_BOARD_INFO("lm90", 0x4c) },
+ { I2C_BOARD_INFO("lm90", 0x4d) },
+ { I2C_BOARD_INFO("adm1021", 0x18) },
+ { I2C_BOARD_INFO("adm1021", 0x19) },
+ { I2C_BOARD_INFO("adm1021", 0x1a) },
+ { I2C_BOARD_INFO("adm1021", 0x29) },
+ { I2C_BOARD_INFO("adm1021", 0x2a) },
+ { I2C_BOARD_INFO("adm1021", 0x2b) },
+ { I2C_BOARD_INFO("adm1021", 0x4c) },
+ { I2C_BOARD_INFO("adm1021", 0x4d) },
+ { I2C_BOARD_INFO("adm1021", 0x4e) },
+ { I2C_BOARD_INFO("lm63", 0x18) },
+ { I2C_BOARD_INFO("lm63", 0x4e) },
{ }
};
@@ -90,9 +89,9 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm)
struct nvbios_extdev_func extdev_entry;
if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_LM89, &extdev_entry)) {
- struct nouveau_i2c_board_info board[] = {
- { { I2C_BOARD_INFO("lm90", extdev_entry.addr >> 1) }, 0},
- { }
+ struct i2c_board_info board[] = {
+ { I2C_BOARD_INFO("lm90", extdev_entry.addr >> 1) },
+ { }
};
i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
@@ -102,9 +101,9 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm)
}
if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_ADT7473, &extdev_entry)) {
- struct nouveau_i2c_board_info board[] = {
- { { I2C_BOARD_INFO("adt7473", extdev_entry.addr >> 1) }, 20 },
- { }
+ struct i2c_board_info board[] = {
+ { I2C_BOARD_INFO("adt7473", extdev_entry.addr >> 1) },
+ { }
};
i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
index 1d15c52..42ba633 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
@@ -126,7 +126,7 @@ nv84_therm_intr(struct nouveau_subdev *subdev)
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
- intr = nv_rd32(therm, 0x20100) & 0x3ff;
+ intr = nv_rd32(therm, 0x20100);
/* THRS_4: downclock */
if (intr & 0x002) {
@@ -209,19 +209,6 @@ nv84_therm_ctor(struct nouveau_object *parent,
return nouveau_therm_preinit(&priv->base.base);
}
-int
-nv84_therm_fini(struct nouveau_object *object, bool suspend)
-{
- /* Disable PTherm IRQs */
- nv_wr32(object, 0x20000, 0x00000000);
-
- /* ACK all PTherm IRQs */
- nv_wr32(object, 0x20100, 0xffffffff);
- nv_wr32(object, 0x1100, 0x10000); /* PBUS */
-
- return _nouveau_therm_fini(object, suspend);
-}
-
struct nouveau_oclass
nv84_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x84),
@@ -229,6 +216,6 @@ nv84_therm_oclass = {
.ctor = nv84_therm_ctor,
.dtor = _nouveau_therm_dtor,
.init = _nouveau_therm_init,
- .fini = nv84_therm_fini,
+ .fini = _nouveau_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
index 3b2c458..d11a7c4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
@@ -94,6 +94,6 @@ nva3_therm_oclass = {
.ctor = nva3_therm_ctor,
.dtor = _nouveau_therm_dtor,
.init = nva3_therm_init,
- .fini = nv84_therm_fini,
+ .fini = _nouveau_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
index 4dd4f81..54c28bd 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
@@ -148,6 +148,6 @@ nvd0_therm_oclass = {
.ctor = nvd0_therm_ctor,
.dtor = _nouveau_therm_dtor,
.init = nvd0_therm_init,
- .fini = nv84_therm_fini,
+ .fini = _nouveau_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
index 96f8f95..dd38529 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
@@ -76,7 +76,6 @@ struct nouveau_therm_priv {
spinlock_t lock;
struct nouveau_therm_trip_point *last_trip;
int mode;
- int cstate;
int suspend;
/* bios */
@@ -145,7 +144,6 @@ int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *);
int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32);
int nv50_fan_pwm_clock(struct nouveau_therm *);
int nv84_temp_get(struct nouveau_therm *therm);
-int nv84_therm_fini(struct nouveau_object *object, bool suspend);
int nva3_therm_fan_sense(struct nouveau_therm *);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
index cfde9eb..b80a330 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
@@ -180,6 +180,8 @@ alarm_timer_callback(struct nouveau_alarm *alarm)
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
+ nv_debug(therm, "polling the internal temperature\n");
+
nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_fan_boost,
NOUVEAU_THERM_THRS_FANBOOST);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
index c0bdd10..57711ec 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
@@ -119,8 +119,16 @@ nv04_timer_alarm_cancel(struct nouveau_timer *ptimer,
{
struct nv04_timer_priv *priv = (void *)ptimer;
unsigned long flags;
+
+ /* avoid deleting an entry while the alarm intr is running */
spin_lock_irqsave(&priv->lock, flags);
- list_del_init(&alarm->head);
+
+ /* delete the alarm from the list */
+ list_del(&alarm->head);
+
+ /* reset the head so as list_empty returns 1 */
+ INIT_LIST_HEAD(&alarm->head);
+
spin_unlock_irqrestore(&priv->lock, flags);
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c
deleted file mode 100644
index 32794a9..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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/volt.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/vmap.h>
-#include <subdev/bios/volt.h>
-
-static int
-nouveau_volt_get(struct nouveau_volt *volt)
-{
- if (volt->vid_get) {
- int ret = volt->vid_get(volt), i;
- if (ret >= 0) {
- for (i = 0; i < volt->vid_nr; i++) {
- if (volt->vid[i].vid == ret)
- return volt->vid[i].uv;
- }
- ret = -EINVAL;
- }
- return ret;
- }
- return -ENODEV;
-}
-
-static int
-nouveau_volt_set(struct nouveau_volt *volt, u32 uv)
-{
- if (volt->vid_set) {
- int i, ret = -EINVAL;
- for (i = 0; i < volt->vid_nr; i++) {
- if (volt->vid[i].uv == uv) {
- ret = volt->vid_set(volt, volt->vid[i].vid);
- nv_debug(volt, "set %duv: %d\n", uv, ret);
- break;
- }
- }
- return ret;
- }
- return -ENODEV;
-}
-
-static int
-nouveau_volt_map(struct nouveau_volt *volt, u8 id)
-{
- struct nouveau_bios *bios = nouveau_bios(volt);
- struct nvbios_vmap_entry info;
- u8 ver, len;
- u16 vmap;
-
- vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
- if (vmap) {
- if (info.link != 0xff) {
- int ret = nouveau_volt_map(volt, info.link);
- if (ret < 0)
- return ret;
- info.min += ret;
- }
- return info.min;
- }
-
- return id ? id * 10000 : -ENODEV;
-}
-
-static int
-nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
-{
- int ret = nouveau_volt_map(volt, id);
- if (ret >= 0) {
- int prev = nouveau_volt_get(volt);
- if (!condition || prev < 0 ||
- (condition < 0 && ret < prev) ||
- (condition > 0 && ret > prev)) {
- ret = nouveau_volt_set(volt, ret);
- } else {
- ret = 0;
- }
- }
- return ret;
-}
-
-int
-_nouveau_volt_init(struct nouveau_object *object)
-{
- struct nouveau_volt *volt = (void *)object;
- int ret;
-
- ret = nouveau_subdev_init(&volt->base);
- if (ret)
- return ret;
-
- ret = volt->get(volt);
- if (ret < 0) {
- if (ret != -ENODEV)
- nv_debug(volt, "current voltage unknown\n");
- return 0;
- }
-
- nv_info(volt, "GPU voltage: %duv\n", ret);
- return 0;
-}
-
-void
-_nouveau_volt_dtor(struct nouveau_object *object)
-{
- struct nouveau_volt *volt = (void *)object;
- nouveau_subdev_destroy(&volt->base);
-}
-
-int
-nouveau_volt_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
-{
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nouveau_volt *volt;
- struct nvbios_volt_entry ivid;
- struct nvbios_volt info;
- u8 ver, hdr, cnt, len;
- u16 data;
- int ret, i;
-
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT",
- "voltage", length, pobject);
- volt = *pobject;
- if (ret)
- return ret;
-
- volt->get = nouveau_volt_get;
- volt->set = nouveau_volt_set;
- volt->set_id = nouveau_volt_set_id;
-
- data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
- if (data && info.vidmask && info.base && info.step) {
- for (i = 0; i < info.vidmask + 1; i++) {
- if (info.base >= info.min &&
- info.base <= info.max) {
- volt->vid[volt->vid_nr].uv = info.base;
- volt->vid[volt->vid_nr].vid = i;
- volt->vid_nr++;
- }
- info.base += info.step;
- }
- volt->vid_mask = info.vidmask;
- } else
- if (data && info.vidmask) {
- for (i = 0; i < cnt; i++) {
- data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
- &ivid);
- if (data) {
- volt->vid[volt->vid_nr].uv = ivid.voltage;
- volt->vid[volt->vid_nr].vid = ivid.vid;
- volt->vid_nr++;
- }
- }
- volt->vid_mask = info.vidmask;
- }
-
- if (volt->vid_nr) {
- for (i = 0; i < volt->vid_nr; i++) {
- nv_debug(volt, "VID %02x: %duv\n",
- volt->vid[i].vid, volt->vid[i].uv);
- }
-
- /*XXX: this is an assumption.. there probably exists boards
- * out there with i2c-connected voltage controllers too..
- */
- ret = nouveau_voltgpio_init(volt);
- if (ret == 0) {
- volt->vid_get = nouveau_voltgpio_get;
- volt->vid_set = nouveau_voltgpio_set;
- }
- }
-
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c b/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c
deleted file mode 100644
index 755fa91..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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/volt.h>
-#include <subdev/gpio.h>
-#include <subdev/bios/gpio.h>
-
-static const u8 tags[] = {
- DCB_GPIO_VID0, DCB_GPIO_VID1, DCB_GPIO_VID2, DCB_GPIO_VID3,
- DCB_GPIO_VID4, DCB_GPIO_VID5, DCB_GPIO_VID6, DCB_GPIO_VID7,
-};
-
-int
-nouveau_voltgpio_get(struct nouveau_volt *volt)
-{
- struct nouveau_gpio *gpio = nouveau_gpio(volt);
- u8 vid = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(tags); i++) {
- if (volt->vid_mask & (1 << i)) {
- int ret = gpio->get(gpio, 0, tags[i], 0xff);
- if (ret < 0)
- return ret;
- vid |= ret << i;
- }
- }
-
- return vid;
-}
-
-int
-nouveau_voltgpio_set(struct nouveau_volt *volt, u8 vid)
-{
- struct nouveau_gpio *gpio = nouveau_gpio(volt);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(tags); i++, vid >>= 1) {
- if (volt->vid_mask & (1 << i)) {
- int ret = gpio->set(gpio, 0, tags[i], 0xff, vid & 1);
- if (ret < 0)
- return ret;
- }
- }
-
- return 0;
-}
-
-int
-nouveau_voltgpio_init(struct nouveau_volt *volt)
-{
- struct nouveau_gpio *gpio = nouveau_gpio(volt);
- struct dcb_gpio_func func;
- int i;
-
- /* check we have gpio function info for each vid bit. on some
- * boards (ie. nvs295) the vid mask has more bits than there
- * are valid gpio functions... from traces, nvidia appear to
- * just touch the existing ones, so let's mask off the invalid
- * bits and continue with life
- */
- for (i = 0; i < ARRAY_SIZE(tags); i++) {
- if (volt->vid_mask & (1 << i)) {
- int ret = gpio->find(gpio, 0, tags[i], 0xff, &func);
- if (ret) {
- if (ret != -ENOENT)
- return ret;
- nv_debug(volt, "VID bit %d has no GPIO\n", i);
- volt->vid_mask &= ~(1 << i);
- }
- }
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c
deleted file mode 100644
index 87d5358..0000000
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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/volt.h>
-
-struct nv40_volt_priv {
- struct nouveau_volt base;
-};
-
-static int
-nv40_volt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv40_volt_priv *priv;
- int ret;
-
- ret = nouveau_volt_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- return 0;
-}
-
-struct nouveau_oclass
-nv40_volt_oclass = {
- .handle = NV_SUBDEV(VOLT, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_volt_ctor,
- .dtor = _nouveau_volt_dtor,
- .init = _nouveau_volt_init,
- .fini = _nouveau_volt_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/dispnv04/Makefile b/drivers/gpu/drm/nouveau/dispnv04/Makefile
index 424a489..ea3f5b8 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/Makefile
+++ b/drivers/gpu/drm/nouveau/dispnv04/Makefile
@@ -5,7 +5,6 @@ nouveau-y += dispnv04/dac.o
nouveau-y += dispnv04/dfp.o
nouveau-y += dispnv04/disp.o
nouveau-y += dispnv04/hw.o
-nouveau-y += dispnv04/overlay.o
nouveau-y += dispnv04/tvmodesnv17.o
nouveau-y += dispnv04/tvnv04.o
nouveau-y += dispnv04/tvnv17.o
diff --git a/drivers/gpu/drm/nouveau/dispnv04/arb.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c
index 2a15b98..2e70462 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/arb.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c
@@ -210,8 +210,8 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
sim_data.nvclk_khz = NVClk;
sim_data.bpp = bpp;
sim_data.two_heads = nv_two_heads(dev);
- if ((dev->pdev->device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ ||
- (dev->pdev->device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) {
+ if ((dev->pci_device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ ||
+ (dev->pci_device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) {
uint32_t type;
pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type);
@@ -256,8 +256,8 @@ nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm
if (nv_device(drm->device)->card_type < NV_20)
nv04_update_arb(dev, vclk, bpp, burst, lwm);
- else if ((dev->pdev->device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ ||
- (dev->pdev->device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) {
+ else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ ||
+ (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) {
*burst = 128;
*lwm = 0x0480;
} else
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 0e3270c..d4fbf11 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -326,6 +326,8 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
regp->MiscOutReg = 0x23; /* +hsync +vsync */
}
+ regp->MiscOutReg |= (mode->clock_index & 0x03) << 2;
+
/*
* Time Sequencer
*/
diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
index 936a71c..93dd23ff 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
@@ -490,10 +490,10 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
/* BIOS scripts usually take care of the backlight, thanks
* Apple for your consistency.
*/
- if (dev->pdev->device == 0x0174 || dev->pdev->device == 0x0179 ||
- dev->pdev->device == 0x0189 || dev->pdev->device == 0x0329) {
+ if (dev->pci_device == 0x0174 || dev->pci_device == 0x0179 ||
+ dev->pci_device == 0x0189 || dev->pci_device == 0x0329) {
if (mode == DRM_MODE_DPMS_ON) {
- nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 1 << 31);
+ nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31);
nv_mask(device, NV_PCRTC_GPIO_EXT, 3, 1);
} else {
nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0);
@@ -625,15 +625,13 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
struct nouveau_i2c_port *port = i2c->find(i2c, 2);
- struct nouveau_i2c_board_info info[] = {
+ struct i2c_board_info info[] = {
{
- {
- .type = "sil164",
- .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38),
- .platform_data = &(struct sil164_encoder_params) {
- SIL164_INPUT_EDGE_RISING
- }
- }, 0
+ .type = "sil164",
+ .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38),
+ .platform_data = &(struct sil164_encoder_params) {
+ SIL164_INPUT_EDGE_RISING
+ }
},
{ }
};
@@ -648,7 +646,7 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder)
return;
drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
- &port->adapter, &info[type].dev);
+ &port->adapter, &info[type]);
}
static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c
index b13ff0f..4908d3f 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c
@@ -140,8 +140,6 @@ nv04_display_create(struct drm_device *dev)
func->save(encoder);
}
- nouveau_overlay_init(dev);
-
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.h b/drivers/gpu/drm/nouveau/dispnv04/disp.h
index 56a28db..9928187 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/disp.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/disp.h
@@ -123,14 +123,11 @@ int nv04_tv_create(struct drm_connector *, struct dcb_output *);
/* nv17_tv.c */
int nv17_tv_create(struct drm_connector *, struct dcb_output *);
-/* overlay.c */
-void nouveau_overlay_init(struct drm_device *dev);
-
static inline bool
nv_two_heads(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- const int impl = dev->pdev->device & 0x0ff0;
+ const int impl = dev->pci_device & 0x0ff0;
if (nv_device(drm->device)->card_type >= NV_10 && impl != 0x0100 &&
impl != 0x0150 && impl != 0x01a0 && impl != 0x0200)
@@ -142,14 +139,14 @@ nv_two_heads(struct drm_device *dev)
static inline bool
nv_gf4_disp_arch(struct drm_device *dev)
{
- return nv_two_heads(dev) && (dev->pdev->device & 0x0ff0) != 0x0110;
+ return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110;
}
static inline bool
nv_two_reg_pll(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- const int impl = dev->pdev->device & 0x0ff0;
+ const int impl = dev->pci_device & 0x0ff0;
if (impl == 0x0310 || impl == 0x0340 || nv_device(drm->device)->card_type >= NV_40)
return true;
diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c
index aca76af..973056b 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/hw.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c
@@ -27,7 +27,6 @@
#include "hw.h"
#include <subdev/bios/pll.h>
-#include <subdev/fb.h>
#include <subdev/clock.h>
#include <subdev/timer.h>
@@ -221,7 +220,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
int ret;
if (plltype == PLL_MEMORY &&
- (dev->pdev->device & 0x0ff0) == CHIPSET_NFORCE) {
+ (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) {
uint32_t mpllP;
pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP);
@@ -231,7 +230,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
return 400000 / mpllP;
} else
if (plltype == PLL_MEMORY &&
- (dev->pdev->device & 0xff0) == CHIPSET_NFORCE2) {
+ (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) {
uint32_t clock;
pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock);
@@ -665,7 +664,6 @@ nv_load_state_ext(struct drm_device *dev, int head,
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_device *device = nv_device(drm->device);
struct nouveau_timer *ptimer = nouveau_timer(device);
- struct nouveau_fb *pfb = nouveau_fb(device);
struct nv04_crtc_reg *regp = &state->crtc_reg[head];
uint32_t reg900;
int i;
@@ -682,10 +680,10 @@ nv_load_state_ext(struct drm_device *dev, int head,
nv_wr32(device, NV_PVIDEO_INTR_EN, 0);
nv_wr32(device, NV_PVIDEO_OFFSET_BUFF(0), 0);
nv_wr32(device, NV_PVIDEO_OFFSET_BUFF(1), 0);
- nv_wr32(device, NV_PVIDEO_LIMIT(0), pfb->ram->size - 1);
- nv_wr32(device, NV_PVIDEO_LIMIT(1), pfb->ram->size - 1);
- nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(0), pfb->ram->size - 1);
- nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(1), pfb->ram->size - 1);
+ nv_wr32(device, NV_PVIDEO_LIMIT(0), 0); //drm->fb_available_size - 1);
+ nv_wr32(device, NV_PVIDEO_LIMIT(1), 0); //drm->fb_available_size - 1);
+ nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(0), 0); //drm->fb_available_size - 1);
+ nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(1), 0); //drm->fb_available_size - 1);
nv_wr32(device, NV_PBUS_POWERCTRL_2, 0);
NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg);
@@ -742,7 +740,7 @@ nv_load_state_ext(struct drm_device *dev, int head,
}
/* NV11 and NV20 stop at 0x52. */
if (nv_gf4_disp_arch(dev)) {
- if (nv_device(drm->device)->card_type < NV_20) {
+ if (nv_device(drm->device)->card_type == NV_10) {
/* Not waiting for vertical retrace before modifying
CRE_53/CRE_54 causes lockups. */
nouveau_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
deleted file mode 100644
index 32e7064..0000000
--- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * 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 AUTHORS 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.
- *
- * Implementation based on the pre-KMS implementation in xf86-video-nouveau,
- * written by Arthur Huillet.
- */
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_fourcc.h>
-
-#include "nouveau_drm.h"
-
-#include "nouveau_bo.h"
-#include "nouveau_connector.h"
-#include "nouveau_display.h"
-#include "nvreg.h"
-
-
-struct nouveau_plane {
- struct drm_plane base;
- bool flip;
- struct nouveau_bo *cur;
-
- struct {
- struct drm_property *colorkey;
- struct drm_property *contrast;
- struct drm_property *brightness;
- struct drm_property *hue;
- struct drm_property *saturation;
- struct drm_property *iturbt_709;
- } props;
-
- int colorkey;
- int contrast;
- int brightness;
- int hue;
- int saturation;
- int iturbt_709;
-};
-
-static uint32_t formats[] = {
- DRM_FORMAT_UYVY,
- DRM_FORMAT_NV12,
-};
-
-/* Sine can be approximated with
- * http://en.wikipedia.org/wiki/Bhaskara_I's_sine_approximation_formula
- * sin(x degrees) ~= 4 x (180 - x) / (40500 - x (180 - x) )
- * Note that this only works for the range [0, 180].
- * Also note that sin(x) == -sin(x - 180)
- */
-static inline int
-sin_mul(int degrees, int factor)
-{
- if (degrees > 180) {
- degrees -= 180;
- factor *= -1;
- }
- return factor * 4 * degrees * (180 - degrees) /
- (40500 - degrees * (180 - degrees));
-}
-
-/* cos(x) = sin(x + 90) */
-static inline int
-cos_mul(int degrees, int factor)
-{
- return sin_mul((degrees + 90) % 360, factor);
-}
-
-static int
-nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h)
-{
- struct nouveau_device *dev = nouveau_dev(plane->dev);
- struct nouveau_plane *nv_plane = (struct nouveau_plane *)plane;
- struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct nouveau_bo *cur = nv_plane->cur;
- bool flip = nv_plane->flip;
- int soff = NV_PCRTC0_SIZE * nv_crtc->index;
- int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index;
- int format, ret;
-
- /* Source parameters given in 16.16 fixed point, ignore fractional. */
- src_x >>= 16;
- src_y >>= 16;
- src_w >>= 16;
- src_h >>= 16;
-
- format = ALIGN(src_w * 4, 0x100);
-
- if (format > 0xffff)
- return -ERANGE;
-
- if (dev->chipset >= 0x30) {
- if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1))
- return -ERANGE;
- } else {
- if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3))
- return -ERANGE;
- }
-
- ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM);
- if (ret)
- return ret;
-
- nv_plane->cur = nv_fb->nvbo;
-
- nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff, NV_CRTC_FSEL_OVERLAY, NV_CRTC_FSEL_OVERLAY);
- nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff2, NV_CRTC_FSEL_OVERLAY, 0);
-
- nv_wr32(dev, NV_PVIDEO_BASE(flip), 0);
- nv_wr32(dev, NV_PVIDEO_OFFSET_BUFF(flip), nv_fb->nvbo->bo.offset);
- nv_wr32(dev, NV_PVIDEO_SIZE_IN(flip), src_h << 16 | src_w);
- nv_wr32(dev, NV_PVIDEO_POINT_IN(flip), src_y << 16 | src_x);
- nv_wr32(dev, NV_PVIDEO_DS_DX(flip), (src_w << 20) / crtc_w);
- nv_wr32(dev, NV_PVIDEO_DT_DY(flip), (src_h << 20) / crtc_h);
- nv_wr32(dev, NV_PVIDEO_POINT_OUT(flip), crtc_y << 16 | crtc_x);
- nv_wr32(dev, NV_PVIDEO_SIZE_OUT(flip), crtc_h << 16 | crtc_w);
-
- if (fb->pixel_format == DRM_FORMAT_NV12) {
- format |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8;
- format |= NV_PVIDEO_FORMAT_PLANAR;
- }
- if (nv_plane->iturbt_709)
- format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
- if (nv_plane->colorkey & (1 << 24))
- format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY;
-
- if (fb->pixel_format == DRM_FORMAT_NV12) {
- nv_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0);
- nv_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip),
- nv_fb->nvbo->bo.offset + fb->offsets[1]);
- }
- nv_wr32(dev, NV_PVIDEO_FORMAT(flip), format);
- nv_wr32(dev, NV_PVIDEO_STOP, 0);
- /* TODO: wait for vblank? */
- nv_wr32(dev, NV_PVIDEO_BUFFER, flip ? 0x10 : 0x1);
- nv_plane->flip = !flip;
-
- if (cur)
- nouveau_bo_unpin(cur);
-
- return 0;
-}
-
-static int
-nv10_disable_plane(struct drm_plane *plane)
-{
- struct nouveau_device *dev = nouveau_dev(plane->dev);
- struct nouveau_plane *nv_plane = (struct nouveau_plane *)plane;
-
- nv_wr32(dev, NV_PVIDEO_STOP, 1);
- if (nv_plane->cur) {
- nouveau_bo_unpin(nv_plane->cur);
- nv_plane->cur = NULL;
- }
-
- return 0;
-}
-
-static void
-nv10_destroy_plane(struct drm_plane *plane)
-{
- nv10_disable_plane(plane);
- drm_plane_cleanup(plane);
- kfree(plane);
-}
-
-static void
-nv10_set_params(struct nouveau_plane *plane)
-{
- struct nouveau_device *dev = nouveau_dev(plane->base.dev);
- u32 luma = (plane->brightness - 512) << 16 | plane->contrast;
- u32 chroma = ((sin_mul(plane->hue, plane->saturation) & 0xffff) << 16) |
- (cos_mul(plane->hue, plane->saturation) & 0xffff);
- u32 format = 0;
-
- nv_wr32(dev, NV_PVIDEO_LUMINANCE(0), luma);
- nv_wr32(dev, NV_PVIDEO_LUMINANCE(1), luma);
- nv_wr32(dev, NV_PVIDEO_CHROMINANCE(0), chroma);
- nv_wr32(dev, NV_PVIDEO_CHROMINANCE(1), chroma);
- nv_wr32(dev, NV_PVIDEO_COLOR_KEY, plane->colorkey & 0xffffff);
-
- if (plane->cur) {
- if (plane->iturbt_709)
- format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
- if (plane->colorkey & (1 << 24))
- format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY;
- nv_mask(dev, NV_PVIDEO_FORMAT(plane->flip),
- NV_PVIDEO_FORMAT_MATRIX_ITURBT709 |
- NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY,
- format);
- }
-}
-
-static int
-nv10_set_property(struct drm_plane *plane,
- struct drm_property *property,
- uint64_t value)
-{
- struct nouveau_plane *nv_plane = (struct nouveau_plane *)plane;
-
- if (property == nv_plane->props.colorkey)
- nv_plane->colorkey = value;
- else if (property == nv_plane->props.contrast)
- nv_plane->contrast = value;
- else if (property == nv_plane->props.brightness)
- nv_plane->brightness = value;
- else if (property == nv_plane->props.hue)
- nv_plane->hue = value;
- else if (property == nv_plane->props.saturation)
- nv_plane->saturation = value;
- else if (property == nv_plane->props.iturbt_709)
- nv_plane->iturbt_709 = value;
- else
- return -EINVAL;
-
- nv10_set_params(nv_plane);
- return 0;
-}
-
-static const struct drm_plane_funcs nv10_plane_funcs = {
- .update_plane = nv10_update_plane,
- .disable_plane = nv10_disable_plane,
- .set_property = nv10_set_property,
- .destroy = nv10_destroy_plane,
-};
-
-static void
-nv10_overlay_init(struct drm_device *device)
-{
- struct nouveau_device *dev = nouveau_dev(device);
- struct nouveau_plane *plane = kzalloc(sizeof(struct nouveau_plane), GFP_KERNEL);
- int num_formats = ARRAY_SIZE(formats);
- int ret;
-
- if (!plane)
- return;
-
- switch (dev->chipset) {
- case 0x10:
- case 0x11:
- case 0x15:
- case 0x1a:
- case 0x20:
- num_formats = 1;
- break;
- }
-
- ret = drm_plane_init(device, &plane->base, 3 /* both crtc's */,
- &nv10_plane_funcs,
- formats, num_formats, false);
- if (ret)
- goto err;
-
- /* Set up the plane properties */
- plane->props.colorkey = drm_property_create_range(
- device, 0, "colorkey", 0, 0x01ffffff);
- plane->props.contrast = drm_property_create_range(
- device, 0, "contrast", 0, 8192 - 1);
- plane->props.brightness = drm_property_create_range(
- device, 0, "brightness", 0, 1024);
- plane->props.hue = drm_property_create_range(
- device, 0, "hue", 0, 359);
- plane->props.saturation = drm_property_create_range(
- device, 0, "saturation", 0, 8192 - 1);
- plane->props.iturbt_709 = drm_property_create_range(
- device, 0, "iturbt_709", 0, 1);
- if (!plane->props.colorkey ||
- !plane->props.contrast ||
- !plane->props.brightness ||
- !plane->props.hue ||
- !plane->props.saturation ||
- !plane->props.iturbt_709)
- goto cleanup;
-
- plane->colorkey = 0;
- drm_object_attach_property(&plane->base.base,
- plane->props.colorkey, plane->colorkey);
-
- plane->contrast = 0x1000;
- drm_object_attach_property(&plane->base.base,
- plane->props.contrast, plane->contrast);
-
- plane->brightness = 512;
- drm_object_attach_property(&plane->base.base,
- plane->props.brightness, plane->brightness);
-
- plane->hue = 0;
- drm_object_attach_property(&plane->base.base,
- plane->props.hue, plane->hue);
-
- plane->saturation = 0x1000;
- drm_object_attach_property(&plane->base.base,
- plane->props.saturation, plane->saturation);
-
- plane->iturbt_709 = 0;
- drm_object_attach_property(&plane->base.base,
- plane->props.iturbt_709, plane->iturbt_709);
-
- nv10_set_params(plane);
- nv_wr32(dev, NV_PVIDEO_STOP, 1);
- return;
-cleanup:
- drm_plane_cleanup(&plane->base);
-err:
- kfree(plane);
- nv_error(dev, "Failed to create plane\n");
-}
-
-void
-nouveau_overlay_init(struct drm_device *device)
-{
- struct nouveau_device *dev = nouveau_dev(device);
- if (dev->chipset >= 0x10 && dev->chipset <= 0x40)
- nv10_overlay_init(device);
-}
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
index cc4b208..bf13db4 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
@@ -37,18 +37,15 @@
#include <subdev/i2c.h>
-static struct nouveau_i2c_board_info nv04_tv_encoder_info[] = {
+static struct i2c_board_info nv04_tv_encoder_info[] = {
{
- {
- I2C_BOARD_INFO("ch7006", 0x75),
- .platform_data = &(struct ch7006_encoder_params) {
- CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
- 0, 0, 0,
- CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
- CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
- }
- },
- 0
+ I2C_BOARD_INFO("ch7006", 0x75),
+ .platform_data = &(struct ch7006_encoder_params) {
+ CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
+ 0, 0, 0,
+ CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
+ CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
+ }
},
{ }
};
@@ -232,8 +229,7 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry)
/* Run the slave-specific initialization */
ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
- &port->adapter,
- &nv04_tv_encoder_info[type].dev);
+ &port->adapter, &nv04_tv_encoder_info[type]);
if (ret < 0)
goto fail_cleanup;
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 6828d81..8f467e7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -87,7 +87,6 @@ nouveau_abi16_swclass(struct nouveau_drm *drm)
case NV_04:
return 0x006e;
case NV_10:
- case NV_11:
case NV_20:
case NV_30:
case NV_40:
@@ -131,7 +130,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
if (chan->ntfy) {
nouveau_bo_vma_del(chan->ntfy, &chan->ntfy_vma);
nouveau_bo_unpin(chan->ntfy);
- drm_gem_object_unreference_unlocked(&chan->ntfy->gem);
+ drm_gem_object_unreference_unlocked(chan->ntfy->gem);
}
if (chan->heap.block_size)
@@ -179,10 +178,10 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
getparam->value = device->chipset;
break;
case NOUVEAU_GETPARAM_PCI_VENDOR:
- getparam->value = dev->pdev->vendor;
+ getparam->value = dev->pci_vendor;
break;
case NOUVEAU_GETPARAM_PCI_DEVICE:
- getparam->value = dev->pdev->device;
+ getparam->value = dev->pci_device;
break;
case NOUVEAU_GETPARAM_BUS_TYPE:
if (drm_pci_device_is_agp(dev))
@@ -298,7 +297,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
else
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
- if (device->card_type < NV_10) {
+ if (device->card_type < NV_C0) {
init->subchan[0].handle = 0x00000000;
init->subchan[0].grclass = 0x0000;
init->subchan[1].handle = NvSw;
@@ -321,7 +320,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
goto done;
}
- ret = drm_gem_handle_create(file_priv, &chan->ntfy->gem,
+ ret = drm_gem_handle_create(file_priv, chan->ntfy->gem,
&init->notifier_handle);
if (ret)
goto done;
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 95c7404..dd7d2e1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -253,15 +253,18 @@ static struct vga_switcheroo_handler nouveau_dsm_handler = {
static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
{
- acpi_handle dhandle;
+ acpi_handle dhandle, nvidia_handle;
+ acpi_status status;
int retval = 0;
- dhandle = ACPI_HANDLE(&pdev->dev);
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
return false;
- if (!acpi_has_method(dhandle, "_DSM"))
+ status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle);
+ if (ACPI_FAILURE(status)) {
return false;
+ }
if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER))
retval |= NOUVEAU_DSM_HAS_MUX;
@@ -314,16 +317,6 @@ static bool nouveau_dsm_detect(void)
has_optimus = 1;
}
- while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_3D << 8, pdev)) != NULL) {
- vga_count++;
-
- retval = nouveau_dsm_pci_probe(pdev);
- if (retval & NOUVEAU_DSM_HAS_MUX)
- has_dsm |= 1;
- if (retval & NOUVEAU_DSM_HAS_OPT)
- has_optimus = 1;
- }
-
/* find the optimus DSM or the old v1 DSM */
if (has_optimus == 1) {
acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
@@ -414,7 +407,7 @@ bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected)
return false;
- dhandle = ACPI_HANDLE(&pdev->dev);
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
return false;
@@ -448,7 +441,7 @@ nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
return NULL;
}
- handle = ACPI_HANDLE(&dev->pdev->dev);
+ handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
if (!handle)
return NULL;
diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c
index 2953c4e..6e7a55f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_agp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_agp.c
@@ -11,28 +11,10 @@ MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)");
static int nouveau_agpmode = -1;
module_param_named(agpmode, nouveau_agpmode, int, 0400);
-struct nouveau_agpmode_quirk {
- u16 hostbridge_vendor;
- u16 hostbridge_device;
- u16 chip_vendor;
- u16 chip_device;
- int mode;
-};
-
-static struct nouveau_agpmode_quirk nouveau_agpmode_quirk_list[] = {
- /* VIA Apollo PRO133x / GeForce FX 5600 Ultra, max agpmode 2, fdo #20341 */
- { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 },
-
- {},
-};
-
static unsigned long
-get_agp_mode(struct nouveau_drm *drm, const struct drm_agp_info *info)
+get_agp_mode(struct nouveau_drm *drm, unsigned long mode)
{
struct nouveau_device *device = nv_device(drm->device);
- struct nouveau_agpmode_quirk *quirk = nouveau_agpmode_quirk_list;
- int agpmode = nouveau_agpmode;
- unsigned long mode = info->mode;
/*
* FW seems to be broken on nv18, it makes the card lock up
@@ -42,27 +24,11 @@ get_agp_mode(struct nouveau_drm *drm, const struct drm_agp_info *info)
mode &= ~PCI_AGP_COMMAND_FW;
/*
- * Go through the quirks list and adjust the agpmode accordingly.
- */
- while (agpmode == -1 && quirk->hostbridge_vendor) {
- if (info->id_vendor == quirk->hostbridge_vendor &&
- info->id_device == quirk->hostbridge_device &&
- device->pdev->vendor == quirk->chip_vendor &&
- device->pdev->device == quirk->chip_device) {
- agpmode = quirk->mode;
- nv_info(device, "Forcing agp mode to %dX. Use agpmode to override.\n",
- agpmode);
- break;
- }
- ++quirk;
- }
-
- /*
* AGP mode set in the command line.
*/
- if (agpmode > 0) {
+ if (nouveau_agpmode > 0) {
bool agpv3 = mode & 0x8;
- int rate = agpv3 ? agpmode / 4 : agpmode;
+ int rate = agpv3 ? nouveau_agpmode / 4 : nouveau_agpmode;
mode = (mode & ~0x7) | (rate & 0x7);
}
@@ -124,7 +90,7 @@ nouveau_agp_reset(struct nouveau_drm *drm)
if (ret)
return;
- mode.mode = get_agp_mode(drm, &info);
+ mode.mode = get_agp_mode(drm, info.mode);
mode.mode &= ~PCI_AGP_COMMAND_FW;
ret = drm_agp_enable(dev, mode);
@@ -173,7 +139,7 @@ nouveau_agp_init(struct nouveau_drm *drm)
}
/* see agp.h for the AGPSTAT_* modes available */
- mode.mode = get_agp_mode(drm, &info);
+ mode.mode = get_agp_mode(drm, info.mode);
ret = drm_agp_enable(dev, mode);
if (ret) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index 630f6e8..2ffad21 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -82,7 +82,7 @@ nv40_backlight_init(struct drm_connector *connector)
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = 31;
- bd = backlight_device_register("nv_backlight", connector->kdev, drm,
+ bd = backlight_device_register("nv_backlight", &connector->kdev, drm,
&nv40_bl_ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);
@@ -204,7 +204,7 @@ nv50_backlight_init(struct drm_connector *connector)
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = 100;
- bd = backlight_device_register("nv_backlight", connector->kdev,
+ bd = backlight_device_register("nv_backlight", &connector->kdev,
nv_encoder, ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 4c3feaa..3e72876 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -127,8 +127,8 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_outp
#ifdef __powerpc__
/* Powerbook specific quirks */
if (script == LVDS_RESET &&
- (dev->pdev->device == 0x0179 || dev->pdev->device == 0x0189 ||
- dev->pdev->device == 0x0329))
+ (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 ||
+ dev->pci_device == 0x0329))
nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72);
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index c0fde6b..755c38d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -98,7 +98,12 @@ nv10_bo_put_tile_region(struct drm_device *dev, struct nouveau_drm_tile *tile,
if (tile) {
spin_lock(&drm->tile.lock);
- tile->fence = nouveau_fence_ref(fence);
+ if (fence) {
+ /* Mark it as pending. */
+ tile->fence = fence;
+ nouveau_fence_ref(fence);
+ }
+
tile->used = false;
spin_unlock(&drm->tile.lock);
}
@@ -141,7 +146,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
struct drm_device *dev = drm->dev;
struct nouveau_bo *nvbo = nouveau_bo(bo);
- if (unlikely(nvbo->gem.filp))
+ if (unlikely(nvbo->gem))
DRM_ERROR("bo %p still attached to GEM object\n", bo);
WARN_ON(nvbo->pin_refcnt > 0);
nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
@@ -264,8 +269,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
struct nouveau_fb *pfb = nouveau_fb(drm->device);
u32 vram_pages = pfb->ram->size >> PAGE_SHIFT;
- if ((nv_device(drm->device)->card_type == NV_10 ||
- nv_device(drm->device)->card_type == NV_11) &&
+ if (nv_device(drm->device)->card_type == NV_10 &&
nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
nvbo->bo.mem.num_pages < vram_pages / 4) {
/*
@@ -978,7 +982,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
bool no_wait_gpu, struct ttm_mem_reg *new_mem)
{
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
- struct nouveau_channel *chan = drm->ttm.chan;
+ struct nouveau_channel *chan = chan = drm->ttm.chan;
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct ttm_mem_reg *old_mem = &bo->mem;
int ret;
@@ -1263,7 +1267,7 @@ nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
{
struct nouveau_bo *nvbo = nouveau_bo(bo);
- return drm_vma_node_verify_access(&nvbo->gem.vma_node, filp);
+ return drm_vma_node_verify_access(&nvbo->gem->vma_node, filp);
}
static int
@@ -1457,12 +1461,14 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
void
nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
{
- struct nouveau_fence *new_fence = nouveau_fence_ref(fence);
struct nouveau_fence *old_fence = NULL;
+ if (likely(fence))
+ nouveau_fence_ref(fence);
+
spin_lock(&nvbo->bo.bdev->fence_lock);
old_fence = nvbo->bo.sync_obj;
- nvbo->bo.sync_obj = new_fence;
+ nvbo->bo.sync_obj = fence;
spin_unlock(&nvbo->bo.bdev->fence_lock);
nouveau_fence_unref(&old_fence);
@@ -1545,8 +1551,7 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm,
if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
nouveau_vm_map(vma, nvbo->bo.mem.mm_node);
- else if (nvbo->bo.mem.mem_type == TTM_PL_TT &&
- nvbo->page_shift == vma->vm->vmm->spg_shift) {
+ else if (nvbo->bo.mem.mem_type == TTM_PL_TT) {
if (node->sg)
nouveau_vm_map_sg_table(vma, 0, size, node);
else
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h
index ff17c1f..653dbbb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -27,10 +27,7 @@ struct nouveau_bo {
u32 tile_flags;
struct nouveau_drm_tile *tile;
- /* Only valid if allocated via nouveau_gem_new() and iff you hold a
- * gem reference to it! For debugging, use gem.filp != NULL to test
- * whether it is valid. */
- struct drm_gem_object gem;
+ struct drm_gem_object *gem;
/* protect by the ttm reservation lock */
int pin_refcnt;
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index cc5152b..e84f4c3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -346,17 +346,22 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
OUT_RING(chan, 0x00000000);
- /* allocate software object class (used for fences on <= nv05) */
- if (device->card_type < NV_10) {
+ /* allocate software object class (used for fences on <= nv05, and
+ * to signal flip completion), bind it to a subchannel.
+ */
+ if ((device->card_type < NV_E0) || gart /* nve0: want_nvsw */) {
ret = nouveau_object_new(nv_object(client), chan->handle,
- NvSw, 0x006e, NULL, 0, &object);
+ NvSw, nouveau_abi16_swclass(chan->drm),
+ NULL, 0, &object);
if (ret)
return ret;
swch = (void *)object->parent;
swch->flip = nouveau_flip_complete;
swch->flip_data = chan;
+ }
+ if (device->card_type < NV_C0) {
ret = RING_SPACE(chan, 2);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 1674882..c5b36f9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -100,7 +100,6 @@ static void
nouveau_connector_destroy(struct drm_connector *connector)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
- nouveau_event_ref(NULL, &nv_connector->hpd_func);
kfree(nv_connector->edid);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
@@ -215,10 +214,9 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
} else {
connector->doublescan_allowed = true;
if (nv_device(drm->device)->card_type == NV_20 ||
- ((nv_device(drm->device)->card_type == NV_10 ||
- nv_device(drm->device)->card_type == NV_11) &&
- (dev->pdev->device & 0x0ff0) != 0x0100 &&
- (dev->pdev->device & 0x0ff0) != 0x0150))
+ (nv_device(drm->device)->card_type == NV_10 &&
+ (dev->pci_device & 0x0ff0) != 0x0100 &&
+ (dev->pci_device & 0x0ff0) != 0x0150))
/* HW is broken */
connector->interlace_allowed = false;
else
@@ -934,9 +932,10 @@ nouveau_connector_hotplug_work(struct work_struct *work)
}
static int
-nouveau_connector_hotplug(void *data, int index)
+nouveau_connector_hotplug(struct nouveau_eventh *event, int index)
{
- struct nouveau_connector *nv_connector = data;
+ struct nouveau_connector *nv_connector =
+ container_of(event, struct nouveau_connector, hpd_func);
schedule_work(&nv_connector->hpd_work);
return NVKM_EVENT_KEEP;
}
@@ -1008,16 +1007,10 @@ nouveau_connector_create(struct drm_device *dev, int index)
ret = gpio->find(gpio, 0, hpd[ffs((entry & 0x07033000) >> 12)],
DCB_GPIO_UNUSED, &nv_connector->hpd);
+ nv_connector->hpd_func.func = nouveau_connector_hotplug;
if (ret)
nv_connector->hpd.func = DCB_GPIO_UNUSED;
- if (nv_connector->hpd.func != DCB_GPIO_UNUSED) {
- nouveau_event_new(gpio->events, nv_connector->hpd.line,
- nouveau_connector_hotplug,
- nv_connector,
- &nv_connector->hpd_func);
- }
-
nv_connector->type = nv_connector->dcb[0];
if (drm_conntype_from_dcb(nv_connector->type) ==
DRM_MODE_CONNECTOR_Unknown) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index 264a778..6e399aa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -69,7 +69,7 @@ struct nouveau_connector {
struct dcb_gpio_func hpd;
struct work_struct hpd_work;
- struct nouveau_eventh *hpd_func;
+ struct nouveau_eventh hpd_func;
int dithering_mode;
int dithering_depth;
@@ -107,4 +107,7 @@ nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
struct drm_connector *
nouveau_connector_create(struct drm_device *, int index);
+int
+nouveau_connector_bpp(struct drm_connector *);
+
#endif /* __NOUVEAU_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 29c3efd..7848590 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -26,6 +26,7 @@
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
+#include <drm/ttm/ttm_execbuf_util.h>
#include "nouveau_fbcon.h"
#include "dispnv04/hw.h"
@@ -37,92 +38,19 @@
#include "nouveau_fence.h"
+#include <subdev/bios/gpio.h>
+#include <subdev/gpio.h>
#include <engine/disp.h>
#include <core/class.h>
-static int
-nouveau_display_vblank_handler(void *data, int head)
-{
- struct nouveau_drm *drm = data;
- drm_handle_vblank(drm->dev, head);
- return NVKM_EVENT_KEEP;
-}
-
-int
-nouveau_display_vblank_enable(struct drm_device *dev, int head)
-{
- struct nouveau_display *disp = nouveau_display(dev);
- if (disp) {
- nouveau_event_get(disp->vblank[head]);
- return 0;
- }
- return -EIO;
-}
-
-void
-nouveau_display_vblank_disable(struct drm_device *dev, int head)
-{
- struct nouveau_display *disp = nouveau_display(dev);
- if (disp)
- nouveau_event_put(disp->vblank[head]);
-}
-
-static void
-nouveau_display_vblank_fini(struct drm_device *dev)
-{
- struct nouveau_display *disp = nouveau_display(dev);
- int i;
-
- if (disp->vblank) {
- for (i = 0; i < dev->mode_config.num_crtc; i++)
- nouveau_event_ref(NULL, &disp->vblank[i]);
- kfree(disp->vblank);
- disp->vblank = NULL;
- }
-
- drm_vblank_cleanup(dev);
-}
-
-static int
-nouveau_display_vblank_init(struct drm_device *dev)
-{
- struct nouveau_display *disp = nouveau_display(dev);
- struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_disp *pdisp = nouveau_disp(drm->device);
- int ret, i;
-
- disp->vblank = kzalloc(dev->mode_config.num_crtc *
- sizeof(*disp->vblank), GFP_KERNEL);
- if (!disp->vblank)
- return -ENOMEM;
-
- for (i = 0; i < dev->mode_config.num_crtc; i++) {
- ret = nouveau_event_new(pdisp->vblank, i,
- nouveau_display_vblank_handler,
- drm, &disp->vblank[i]);
- if (ret) {
- nouveau_display_vblank_fini(dev);
- return ret;
- }
- }
-
- ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
- if (ret) {
- nouveau_display_vblank_fini(dev);
- return ret;
- }
-
- return 0;
-}
-
static void
nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
{
struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
if (fb->nvbo)
- drm_gem_object_unreference_unlocked(&fb->nvbo->gem);
+ drm_gem_object_unreference_unlocked(fb->nvbo->gem);
drm_framebuffer_cleanup(drm_fb);
kfree(fb);
@@ -135,7 +63,7 @@ nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb,
{
struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
- return drm_gem_handle_create(file_priv, &fb->nvbo->gem, handle);
+ return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle);
}
static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
@@ -299,7 +227,9 @@ static struct nouveau_drm_prop_enum_list dither_depth[] = {
int
nouveau_display_init(struct drm_device *dev)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_display *disp = nouveau_display(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct drm_connector *connector;
int ret;
@@ -313,7 +243,10 @@ nouveau_display_init(struct drm_device *dev)
/* enable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct nouveau_connector *conn = nouveau_connector(connector);
- if (conn->hpd_func) nouveau_event_get(conn->hpd_func);
+ if (gpio && conn->hpd.func != DCB_GPIO_UNUSED) {
+ nouveau_event_get(gpio->events, conn->hpd.line,
+ &conn->hpd_func);
+ }
}
return ret;
@@ -322,13 +255,18 @@ nouveau_display_init(struct drm_device *dev)
void
nouveau_display_fini(struct drm_device *dev)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_display *disp = nouveau_display(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct drm_connector *connector;
/* disable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct nouveau_connector *conn = nouveau_connector(connector);
- if (conn->hpd_func) nouveau_event_put(conn->hpd_func);
+ if (gpio && conn->hpd.func != DCB_GPIO_UNUSED) {
+ nouveau_event_put(gpio->events, conn->hpd.line,
+ &conn->hpd_func);
+ }
}
drm_kms_helper_poll_disable(dev);
@@ -398,11 +336,6 @@ nouveau_display_create(struct drm_device *dev)
dev->mode_config.preferred_depth = 24;
dev->mode_config.prefer_shadow = 1;
- if (nv_device(drm->device)->chipset < 0x11)
- dev->mode_config.async_page_flip = false;
- else
- dev->mode_config.async_page_flip = true;
-
drm_kms_helper_poll_init(dev);
drm_kms_helper_poll_disable(dev);
@@ -419,7 +352,7 @@ nouveau_display_create(struct drm_device *dev)
goto disp_create_err;
if (dev->mode_config.num_crtc) {
- ret = nouveau_display_vblank_init(dev);
+ ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret)
goto vblank_err;
}
@@ -441,7 +374,7 @@ nouveau_display_destroy(struct drm_device *dev)
struct nouveau_display *disp = nouveau_display(dev);
nouveau_backlight_exit(dev);
- nouveau_display_vblank_fini(dev);
+ drm_vblank_cleanup(dev);
drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev);
@@ -461,7 +394,7 @@ nouveau_display_suspend(struct drm_device *dev)
nouveau_display_fini(dev);
- NV_INFO(drm, "unpinning framebuffer(s)...\n");
+ NV_SUSPEND(drm, "unpinning framebuffer(s)...\n");
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
@@ -559,15 +492,19 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
goto fail;
/* Emit the pageflip */
- ret = RING_SPACE(chan, 2);
+ ret = RING_SPACE(chan, 3);
if (ret)
goto fail;
- if (nv_device(drm->device)->card_type < NV_C0)
+ if (nv_device(drm->device)->card_type < NV_C0) {
BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
- else
- BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1);
- OUT_RING (chan, 0x00000000);
+ OUT_RING (chan, 0x00000000);
+ OUT_RING (chan, 0x00000000);
+ } else {
+ BEGIN_NVC0(chan, 0, NV10_SUBCHAN_REF_CNT, 1);
+ OUT_RING (chan, 0);
+ BEGIN_IMC0(chan, 0, NVSW_SUBCHAN_PAGE_FLIP, 0x0000);
+ }
FIRE_RING (chan);
ret = nouveau_fence_new(chan, false, pfence);
@@ -584,16 +521,22 @@ fail:
int
nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event, u32 flags)
+ struct drm_pending_vblank_event *event,
+ uint32_t page_flip_flags)
{
- const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
struct drm_device *dev = crtc->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo;
struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
struct nouveau_page_flip_state *s;
- struct nouveau_channel *chan = drm->channel;
+ struct nouveau_channel *chan = NULL;
struct nouveau_fence *fence;
+ struct ttm_validate_buffer resv[2] = {
+ { .bo = &old_bo->bo },
+ { .bo = &new_bo->bo },
+ };
+ struct ww_acquire_ctx ticket;
+ LIST_HEAD(res);
int ret;
if (!drm->channel)
@@ -603,23 +546,26 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if (!s)
return -ENOMEM;
- /* synchronise rendering channel with the kernel's channel */
- spin_lock(&new_bo->bo.bdev->fence_lock);
- fence = nouveau_fence_ref(new_bo->bo.sync_obj);
- spin_unlock(&new_bo->bo.bdev->fence_lock);
- ret = nouveau_fence_sync(fence, chan);
- nouveau_fence_unref(&fence);
- if (ret)
- return ret;
+ /* Choose the channel the flip will be handled in */
+ spin_lock(&old_bo->bo.bdev->fence_lock);
+ fence = new_bo->bo.sync_obj;
+ if (fence)
+ chan = fence->channel;
+ if (!chan)
+ chan = drm->channel;
+ spin_unlock(&old_bo->bo.bdev->fence_lock);
if (new_bo != old_bo) {
ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
if (ret)
goto fail_free;
+
+ list_add(&resv[1].head, &res);
}
+ list_add(&resv[0].head, &res);
mutex_lock(&chan->cli->mutex);
- ret = ttm_bo_reserve(&old_bo->bo, true, false, false, NULL);
+ ret = ttm_eu_reserve_buffers(&ticket, &res);
if (ret)
goto fail_unpin;
@@ -631,29 +577,12 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Emit a page flip */
if (nv_device(drm->device)->card_type >= NV_50) {
- ret = nv50_display_flip_next(crtc, fb, chan, swap_interval);
+ ret = nv50_display_flip_next(crtc, fb, chan, 0);
if (ret)
goto fail_unreserve;
} else {
struct nv04_display *dispnv04 = nv04_display(dev);
- int head = nouveau_crtc(crtc)->index;
-
- if (swap_interval) {
- ret = RING_SPACE(chan, 8);
- if (ret)
- goto fail_unreserve;
-
- BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
- OUT_RING (chan, 0);
- BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
- OUT_RING (chan, head);
- BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
- OUT_RING (chan, 0);
- BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
- OUT_RING (chan, 0);
- }
-
- nouveau_bo_ref(new_bo, &dispnv04->image[head]);
+ nouveau_bo_ref(new_bo, &dispnv04->image[nouveau_crtc(crtc)->index]);
}
ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
@@ -664,15 +593,14 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Update the crtc struct and cleanup */
crtc->fb = fb;
- nouveau_bo_fence(old_bo, fence);
- ttm_bo_unreserve(&old_bo->bo);
+ ttm_eu_fence_buffer_objects(&ticket, &res, fence);
if (old_bo != new_bo)
nouveau_bo_unpin(old_bo);
nouveau_fence_unref(&fence);
return 0;
fail_unreserve:
- ttm_bo_unreserve(&old_bo->bo);
+ ttm_eu_backoff_reservation(&ticket, &res);
fail_unpin:
mutex_unlock(&chan->cli->mutex);
if (old_bo != new_bo)
@@ -702,7 +630,7 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
if (s->event)
- drm_send_vblank_event(dev, s->crtc, s->event);
+ drm_send_vblank_event(dev, -1, s->event);
list_del(&s->head);
if (ps)
@@ -746,8 +674,8 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
if (ret)
return ret;
- ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle);
- drm_gem_object_unreference_unlocked(&bo->gem);
+ ret = drm_gem_handle_create(file_priv, bo->gem, &args->handle);
+ drm_gem_object_unreference_unlocked(bo->gem);
return ret;
}
@@ -760,7 +688,7 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv,
gem = drm_gem_object_lookup(dev, file_priv, handle);
if (gem) {
- struct nouveau_bo *bo = nouveau_gem_object(gem);
+ struct nouveau_bo *bo = gem->driver_private;
*poffset = drm_vma_node_offset_addr(&bo->bo.vma_node);
drm_gem_object_unreference_unlocked(gem);
return 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
index 8bc8bab..025c66f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.h
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
@@ -36,8 +36,6 @@ struct nouveau_display {
int (*init)(struct drm_device *);
void (*fini)(struct drm_device *);
- struct nouveau_eventh **vblank;
-
struct drm_property *dithering_mode;
struct drm_property *dithering_depth;
struct drm_property *underscan_property;
@@ -61,8 +59,6 @@ void nouveau_display_fini(struct drm_device *dev);
int nouveau_display_suspend(struct drm_device *dev);
void nouveau_display_repin(struct drm_device *dev);
void nouveau_display_resume(struct drm_device *dev);
-int nouveau_display_vblank_enable(struct drm_device *, int);
-void nouveau_display_vblank_disable(struct drm_device *, int);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h
index 984004d..690d593 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.h
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
@@ -51,11 +51,9 @@ enum {
NvSubCtxSurf2D = 0,
NvSubSw = 1,
NvSubImageBlit = 2,
+ NvSub2D = 3,
NvSubGdiRect = 3,
-
- NvSub2D = 3, /* DO NOT CHANGE - hardcoded for kepler gr fifo */
- NvSubCopy = 4, /* DO NOT CHANGE - hardcoded for kepler gr fifo */
- FermiSw = 5, /* DO NOT CHANGE (well.. 6/7 will work...) */
+ NvSubCopy = 4,
};
/* Object handles. */
@@ -196,6 +194,7 @@ WIND_RING(struct nouveau_channel *chan)
#define NV84_SUBCHAN_UEVENT 0x00000020
#define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024
#define NV10_SUBCHAN_REF_CNT 0x00000050
+#define NVSW_SUBCHAN_PAGE_FLIP 0x00000054
#define NV11_SUBCHAN_DMA_SEMAPHORE 0x00000060
#define NV11_SUBCHAN_SEMAPHORE_OFFSET 0x00000064
#define NV11_SUBCHAN_SEMAPHORE_ACQUIRE 0x00000068
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 7a3759f..e893c53 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -37,7 +37,6 @@
#include <engine/device.h>
#include <engine/disp.h>
#include <engine/fifo.h>
-#include <engine/software.h>
#include <subdev/vm.h>
@@ -47,8 +46,7 @@
#include "nouveau_gem.h"
#include "nouveau_agp.h"
#include "nouveau_vga.h"
-#include "nouveau_sysfs.h"
-#include "nouveau_hwmon.h"
+#include "nouveau_pm.h"
#include "nouveau_acpi.h"
#include "nouveau_bios.h"
#include "nouveau_ioctl.h"
@@ -80,6 +78,41 @@ module_param_named(runpm, nouveau_runtime_pm, int, 0400);
static struct drm_driver driver;
+static int
+nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
+{
+ struct nouveau_drm *drm =
+ container_of(event, struct nouveau_drm, vblank[head]);
+ drm_handle_vblank(drm->dev, head);
+ return NVKM_EVENT_KEEP;
+}
+
+static int
+nouveau_drm_vblank_enable(struct drm_device *dev, int head)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_disp *pdisp = nouveau_disp(drm->device);
+
+ if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank)))
+ return -EIO;
+ WARN_ON_ONCE(drm->vblank[head].func);
+ drm->vblank[head].func = nouveau_drm_vblank_handler;
+ nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]);
+ return 0;
+}
+
+static void
+nouveau_drm_vblank_disable(struct drm_device *dev, int head)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_disp *pdisp = nouveau_disp(drm->device);
+ if (drm->vblank[head].func)
+ nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]);
+ else
+ WARN_ON_ONCE(1);
+ drm->vblank[head].func = NULL;
+}
+
static u64
nouveau_name(struct pci_dev *pdev)
{
@@ -144,8 +177,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
/* initialise synchronisation routines */
if (device->card_type < NV_10) ret = nv04_fence_create(drm);
- else if (device->card_type < NV_11 ||
- device->chipset < 0x17) ret = nv10_fence_create(drm);
+ else if (device->chipset < 0x17) ret = nv10_fence_create(drm);
else if (device->card_type < NV_50) ret = nv17_fence_create(drm);
else if (device->chipset < 0x84) ret = nv50_fence_create(drm);
else if (device->card_type < NV_C0) ret = nv84_fence_create(drm);
@@ -192,32 +224,6 @@ nouveau_accel_init(struct nouveau_drm *drm)
return;
}
- ret = nouveau_object_new(nv_object(drm), NVDRM_CHAN, NVDRM_NVSW,
- nouveau_abi16_swclass(drm), NULL, 0, &object);
- if (ret == 0) {
- struct nouveau_software_chan *swch = (void *)object->parent;
- ret = RING_SPACE(drm->channel, 2);
- if (ret == 0) {
- if (device->card_type < NV_C0) {
- BEGIN_NV04(drm->channel, NvSubSw, 0, 1);
- OUT_RING (drm->channel, NVDRM_NVSW);
- } else
- if (device->card_type < NV_E0) {
- BEGIN_NVC0(drm->channel, FermiSw, 0, 1);
- OUT_RING (drm->channel, 0x001f0000);
- }
- }
- swch = (void *)object->parent;
- swch->flip = nouveau_flip_complete;
- swch->flip_data = drm->channel;
- }
-
- if (ret) {
- NV_ERROR(drm, "failed to allocate software object, %d\n", ret);
- nouveau_accel_fini(drm);
- return;
- }
-
if (device->card_type < NV_C0) {
ret = nouveau_gpuobj_new(drm->device, NULL, 32, 0, 0,
&drm->notify);
@@ -412,8 +418,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
goto fail_dispinit;
}
- nouveau_sysfs_init(dev);
- nouveau_hwmon_init(dev);
+ nouveau_pm_init(dev);
+
nouveau_accel_init(drm);
nouveau_fbcon_init(dev);
@@ -449,8 +455,8 @@ nouveau_drm_unload(struct drm_device *dev)
pm_runtime_get_sync(dev->dev);
nouveau_fbcon_fini(dev);
nouveau_accel_fini(drm);
- nouveau_hwmon_fini(dev);
- nouveau_sysfs_fini(dev);
+
+ nouveau_pm_fini(dev);
if (dev->mode_config.num_crtc)
nouveau_display_fini(dev);
@@ -490,16 +496,16 @@ nouveau_do_suspend(struct drm_device *dev)
int ret;
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "suspending display...\n");
+ NV_SUSPEND(drm, "suspending display...\n");
ret = nouveau_display_suspend(dev);
if (ret)
return ret;
}
- NV_INFO(drm, "evicting buffers...\n");
+ NV_SUSPEND(drm, "evicting buffers...\n");
ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
- NV_INFO(drm, "waiting for kernel channels to go idle...\n");
+ NV_SUSPEND(drm, "waiting for kernel channels to go idle...\n");
if (drm->cechan) {
ret = nouveau_channel_idle(drm->cechan);
if (ret)
@@ -512,7 +518,7 @@ nouveau_do_suspend(struct drm_device *dev)
return ret;
}
- NV_INFO(drm, "suspending client object trees...\n");
+ NV_SUSPEND(drm, "suspending client object trees...\n");
if (drm->fence && nouveau_fence(drm)->suspend) {
if (!nouveau_fence(drm)->suspend(drm))
return -ENOMEM;
@@ -524,7 +530,7 @@ nouveau_do_suspend(struct drm_device *dev)
goto fail_client;
}
- NV_INFO(drm, "suspending kernel object tree...\n");
+ NV_SUSPEND(drm, "suspending kernel object tree...\n");
ret = nouveau_client_fini(&drm->client.base, true);
if (ret)
goto fail_client;
@@ -538,7 +544,7 @@ fail_client:
}
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "resuming display...\n");
+ NV_SUSPEND(drm, "resuming display...\n");
nouveau_display_resume(dev);
}
return ret;
@@ -557,6 +563,7 @@ int nouveau_pmops_suspend(struct device *dev)
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 1);
+ nv_suspend_set_printk_level(NV_DBG_INFO);
ret = nouveau_do_suspend(drm_dev);
if (ret)
return ret;
@@ -564,6 +571,8 @@ int nouveau_pmops_suspend(struct device *dev)
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
+ nv_suspend_set_printk_level(NV_DBG_DEBUG);
+
return 0;
}
@@ -573,15 +582,15 @@ nouveau_do_resume(struct drm_device *dev)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_cli *cli;
- NV_INFO(drm, "re-enabling device...\n");
+ NV_SUSPEND(drm, "re-enabling device...\n");
nouveau_agp_reset(drm);
- NV_INFO(drm, "resuming kernel object tree...\n");
+ NV_SUSPEND(drm, "resuming kernel object tree...\n");
nouveau_client_init(&drm->client.base);
nouveau_agp_init(drm);
- NV_INFO(drm, "resuming client object trees...\n");
+ NV_SUSPEND(drm, "resuming client object trees...\n");
if (drm->fence && nouveau_fence(drm)->resume)
nouveau_fence(drm)->resume(drm);
@@ -590,9 +599,10 @@ nouveau_do_resume(struct drm_device *dev)
}
nouveau_run_vbios_init(dev);
+ nouveau_pm_resume(dev);
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "resuming display...\n");
+ NV_SUSPEND(drm, "resuming display...\n");
nouveau_display_repin(dev);
}
@@ -616,15 +626,19 @@ int nouveau_pmops_resume(struct device *dev)
return ret;
pci_set_master(pdev);
+ nv_suspend_set_printk_level(NV_DBG_INFO);
ret = nouveau_do_resume(drm_dev);
- if (ret)
+ if (ret) {
+ nv_suspend_set_printk_level(NV_DBG_DEBUG);
return ret;
+ }
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 0);
nouveau_fbcon_zfill_all(drm_dev);
if (drm_dev->mode_config.num_crtc)
nouveau_display_resume(drm_dev);
+ nv_suspend_set_printk_level(NV_DBG_DEBUG);
return 0;
}
@@ -634,10 +648,12 @@ static int nouveau_pmops_freeze(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
+ nv_suspend_set_printk_level(NV_DBG_INFO);
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 1);
ret = nouveau_do_suspend(drm_dev);
+ nv_suspend_set_printk_level(NV_DBG_DEBUG);
return ret;
}
@@ -647,14 +663,18 @@ static int nouveau_pmops_thaw(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
+ nv_suspend_set_printk_level(NV_DBG_INFO);
ret = nouveau_do_resume(drm_dev);
- if (ret)
+ if (ret) {
+ nv_suspend_set_printk_level(NV_DBG_DEBUG);
return ret;
+ }
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 0);
nouveau_fbcon_zfill_all(drm_dev);
if (drm_dev->mode_config.num_crtc)
nouveau_display_resume(drm_dev);
+ nv_suspend_set_printk_level(NV_DBG_DEBUG);
return 0;
}
@@ -796,8 +816,8 @@ driver = {
#endif
.get_vblank_counter = drm_vblank_count,
- .enable_vblank = nouveau_display_vblank_enable,
- .disable_vblank = nouveau_display_vblank_disable,
+ .enable_vblank = nouveau_drm_vblank_enable,
+ .disable_vblank = nouveau_drm_vblank_disable,
.ioctls = nouveau_ioctls,
.num_ioctls = ARRAY_SIZE(nouveau_ioctls),
@@ -814,6 +834,7 @@ driver = {
.gem_prime_vmap = nouveau_gem_prime_vmap,
.gem_prime_vunmap = nouveau_gem_prime_vunmap,
+ .gem_init_object = nouveau_gem_object_new,
.gem_free_object = nouveau_gem_object_del,
.gem_open_object = nouveau_gem_object_open,
.gem_close_object = nouveau_gem_object_close,
@@ -858,7 +879,6 @@ static int nouveau_pmops_runtime_suspend(struct device *dev)
if (nouveau_runtime_pm == 0)
return -EINVAL;
- nv_debug_level(SILENT);
drm_kms_helper_poll_disable(drm_dev);
vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
nouveau_switcheroo_optimus_dsm();
@@ -895,7 +915,6 @@ static int nouveau_pmops_runtime_resume(struct device *dev)
nv_mask(device, 0x88488, (1 << 25), (1 << 25));
vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
- nv_debug_level(NORMAL);
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 4b0fb6c..994fd6e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -51,12 +51,10 @@ struct nouveau_drm_tile {
};
enum nouveau_drm_handle {
- NVDRM_CLIENT = 0xffffffff,
- NVDRM_DEVICE = 0xdddddddd,
- NVDRM_CONTROL = 0xdddddddc,
- NVDRM_PUSH = 0xbbbb0000, /* |= client chid */
- NVDRM_CHAN = 0xcccc0000, /* |= client chid */
- NVDRM_NVSW = 0x55550000,
+ NVDRM_CLIENT = 0xffffffff,
+ NVDRM_DEVICE = 0xdddddddd,
+ NVDRM_PUSH = 0xbbbb0000, /* |= client chid */
+ NVDRM_CHAN = 0xcccc0000, /* |= client chid */
};
struct nouveau_cli {
@@ -129,10 +127,10 @@ struct nouveau_drm {
struct nvbios vbios;
struct nouveau_display *display;
struct backlight_device *backlight;
+ struct nouveau_eventh vblank[4];
/* power management */
- struct nouveau_hwmon *hwmon;
- struct nouveau_sysfs *sysfs;
+ struct nouveau_pm *pm;
/* display power reference */
bool have_disp_power_ref;
@@ -156,6 +154,7 @@ nouveau_dev(struct drm_device *dev)
int nouveau_pmops_suspend(struct device *);
int nouveau_pmops_resume(struct device *);
+#define NV_SUSPEND(cli, fmt, args...) nv_suspend((cli), fmt, ##args)
#define NV_FATAL(cli, fmt, args...) nv_fatal((cli), fmt, ##args)
#define NV_ERROR(cli, fmt, args...) nv_error((cli), fmt, ##args)
#define NV_WARN(cli, fmt, args...) nv_warn((cli), fmt, ##args)
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 7903e0e..a86ecf6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -420,7 +420,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
nouveau_bo_unmap(nouveau_fb->nvbo);
nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma);
nouveau_bo_unpin(nouveau_fb->nvbo);
- drm_gem_object_unreference_unlocked(&nouveau_fb->nvbo->gem);
+ drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
nouveau_fb->nvbo = NULL;
}
drm_fb_helper_fini(&fbcon->helper);
@@ -503,45 +503,34 @@ nouveau_fbcon_fini(struct drm_device *dev)
drm->fbcon = NULL;
}
-void
-nouveau_fbcon_save_disable_accel(struct drm_device *dev)
+void nouveau_fbcon_save_disable_accel(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- if (drm->fbcon) {
- drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
- drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
- }
+
+ drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
+ drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
}
-void
-nouveau_fbcon_restore_accel(struct drm_device *dev)
+void nouveau_fbcon_restore_accel(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- if (drm->fbcon) {
- drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
- }
+ drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
}
-void
-nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
+void nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- if (drm->fbcon) {
- console_lock();
- if (state == 0)
- nouveau_fbcon_save_disable_accel(dev);
- fb_set_suspend(drm->fbcon->helper.fbdev, state);
- if (state == 1)
- nouveau_fbcon_restore_accel(dev);
- console_unlock();
- }
+ console_lock();
+ if (state == 0)
+ nouveau_fbcon_save_disable_accel(dev);
+ fb_set_suspend(drm->fbcon->helper.fbdev, state);
+ if (state == 1)
+ nouveau_fbcon_restore_accel(dev);
+ console_unlock();
}
-void
-nouveau_fbcon_zfill_all(struct drm_device *dev)
+void nouveau_fbcon_zfill_all(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- if (drm->fbcon) {
- nouveau_fbcon_zfill(dev, drm->fbcon);
- }
+ nouveau_fbcon_zfill(dev, drm->fbcon);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 40cf52e..be31499 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -165,11 +165,17 @@ nouveau_fence_done(struct nouveau_fence *fence)
return !fence->channel;
}
+struct nouveau_fence_uevent {
+ struct nouveau_eventh handler;
+ struct nouveau_fence_priv *priv;
+};
+
static int
-nouveau_fence_wait_uevent_handler(void *data, int index)
+nouveau_fence_wait_uevent_handler(struct nouveau_eventh *event, int index)
{
- struct nouveau_fence_priv *priv = data;
- wake_up_all(&priv->waiting);
+ struct nouveau_fence_uevent *uevent =
+ container_of(event, struct nouveau_fence_uevent, handler);
+ wake_up_all(&uevent->priv->waiting);
return NVKM_EVENT_KEEP;
}
@@ -180,16 +186,13 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr)
struct nouveau_channel *chan = fence->channel;
struct nouveau_fifo *pfifo = nouveau_fifo(chan->drm->device);
struct nouveau_fence_priv *priv = chan->drm->fence;
- struct nouveau_eventh *handler;
+ struct nouveau_fence_uevent uevent = {
+ .handler.func = nouveau_fence_wait_uevent_handler,
+ .priv = priv,
+ };
int ret = 0;
- ret = nouveau_event_new(pfifo->uevent, 0,
- nouveau_fence_wait_uevent_handler,
- priv, &handler);
- if (ret)
- return ret;
-
- nouveau_event_get(handler);
+ nouveau_event_get(pfifo->uevent, 0, &uevent.handler);
if (fence->timeout) {
unsigned long timeout = fence->timeout - jiffies;
@@ -221,7 +224,7 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr)
}
}
- nouveau_event_ref(NULL, &handler);
+ nouveau_event_put(pfifo->uevent, 0, &uevent.handler);
if (unlikely(ret < 0))
return ret;
@@ -306,8 +309,7 @@ nouveau_fence_unref(struct nouveau_fence **pfence)
struct nouveau_fence *
nouveau_fence_ref(struct nouveau_fence *fence)
{
- if (fence)
- kref_get(&fence->kref);
+ kref_get(&fence->kref);
return fence;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 78a27f8..f32b712 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -34,20 +34,29 @@
#include "nouveau_ttm.h"
#include "nouveau_gem.h"
+int
+nouveau_gem_object_new(struct drm_gem_object *gem)
+{
+ return 0;
+}
+
void
nouveau_gem_object_del(struct drm_gem_object *gem)
{
- struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+ struct nouveau_bo *nvbo = gem->driver_private;
struct ttm_buffer_object *bo = &nvbo->bo;
+ if (!nvbo)
+ return;
+ nvbo->gem = NULL;
+
if (gem->import_attach)
drm_prime_gem_destroy(gem, nvbo->bo.sg);
- drm_gem_object_release(gem);
-
- /* reset filp so nouveau_bo_del_ttm() can test for it */
- gem->filp = NULL;
ttm_bo_unref(&bo);
+
+ drm_gem_object_release(gem);
+ kfree(gem);
}
int
@@ -106,7 +115,8 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
if (mapped) {
spin_lock(&nvbo->bo.bdev->fence_lock);
- fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+ if (nvbo->bo.sync_obj)
+ fence = nouveau_fence_ref(nvbo->bo.sync_obj);
spin_unlock(&nvbo->bo.bdev->fence_lock);
}
@@ -176,15 +186,14 @@ nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain,
if (nv_device(drm->device)->card_type >= NV_50)
nvbo->valid_domains &= domain;
- /* Initialize the embedded gem-object. We return a single gem-reference
- * to the caller, instead of a normal nouveau_bo ttm reference. */
- ret = drm_gem_object_init(dev, &nvbo->gem, nvbo->bo.mem.size);
- if (ret) {
+ nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size);
+ if (!nvbo->gem) {
nouveau_bo_ref(NULL, pnvbo);
return -ENOMEM;
}
- nvbo->bo.persistent_swap_storage = nvbo->gem.filp;
+ nvbo->bo.persistent_swap_storage = nvbo->gem->filp;
+ nvbo->gem->driver_private = nvbo;
return 0;
}
@@ -241,15 +250,15 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
if (ret)
return ret;
- ret = drm_gem_handle_create(file_priv, &nvbo->gem, &req->info.handle);
+ ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
if (ret == 0) {
- ret = nouveau_gem_info(file_priv, &nvbo->gem, &req->info);
+ ret = nouveau_gem_info(file_priv, nvbo->gem, &req->info);
if (ret)
drm_gem_handle_delete(file_priv, req->info.handle);
}
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(&nvbo->gem);
+ drm_gem_object_unreference_unlocked(nvbo->gem);
return ret;
}
@@ -257,7 +266,7 @@ static int
nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
uint32_t write_domains, uint32_t valid_domains)
{
- struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+ struct nouveau_bo *nvbo = gem->driver_private;
struct ttm_buffer_object *bo = &nvbo->bo;
uint32_t domains = valid_domains & nvbo->valid_domains &
(write_domains ? write_domains : read_domains);
@@ -308,8 +317,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence,
list_for_each_safe(entry, tmp, list) {
nvbo = list_entry(entry, struct nouveau_bo, entry);
- if (likely(fence))
- nouveau_bo_fence(nvbo, fence);
+ nouveau_bo_fence(nvbo, fence);
if (unlikely(nvbo->validate_mapped)) {
ttm_bo_kunmap(&nvbo->kmap);
@@ -319,7 +327,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence,
list_del(&nvbo->entry);
nvbo->reserved_by = NULL;
ttm_bo_unreserve_ticket(&nvbo->bo, ticket);
- drm_gem_object_unreference_unlocked(&nvbo->gem);
+ drm_gem_object_unreference_unlocked(nvbo->gem);
}
}
@@ -368,7 +376,7 @@ retry:
validate_fini(op, NULL);
return -ENOENT;
}
- nvbo = nouveau_gem_object(gem);
+ nvbo = gem->driver_private;
if (nvbo == res_bo) {
res_bo = NULL;
drm_gem_object_unreference_unlocked(gem);
@@ -438,7 +446,8 @@ validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo)
int ret = 0;
spin_lock(&nvbo->bo.bdev->fence_lock);
- fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+ if (nvbo->bo.sync_obj)
+ fence = nouveau_fence_ref(nvbo->bo.sync_obj);
spin_unlock(&nvbo->bo.bdev->fence_lock);
if (fence) {
@@ -469,7 +478,7 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli,
return ret;
}
- ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains,
+ ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
b->write_domains,
b->valid_domains);
if (unlikely(ret)) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h
index 7caca05..502e429 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.h
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.h
@@ -12,13 +12,14 @@
static inline struct nouveau_bo *
nouveau_gem_object(struct drm_gem_object *gem)
{
- return gem ? container_of(gem, struct nouveau_bo, gem) : NULL;
+ return gem ? gem->driver_private : NULL;
}
/* nouveau_gem.c */
extern int nouveau_gem_new(struct drm_device *, int size, int align,
uint32_t domain, uint32_t tile_mode,
uint32_t tile_flags, struct nouveau_bo **);
+extern int nouveau_gem_object_new(struct drm_gem_object *);
extern void nouveau_gem_object_del(struct drm_gem_object *);
extern int nouveau_gem_object_open(struct drm_gem_object *, struct drm_file *);
extern void nouveau_gem_object_close(struct drm_gem_object *,
diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.h b/drivers/gpu/drm/nouveau/nouveau_hwmon.h
deleted file mode 100644
index 62ccbb3..0000000
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2010 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
- */
-
-#ifndef __NOUVEAU_PM_H__
-#define __NOUVEAU_PM_H__
-
-struct nouveau_hwmon {
- struct drm_device *dev;
- struct device *hwmon;
-};
-
-static inline struct nouveau_hwmon *
-nouveau_hwmon(struct drm_device *dev)
-{
- return nouveau_drm(dev)->hwmon;
-}
-
-/* nouveau_hwmon.c */
-int nouveau_hwmon_init(struct drm_device *dev);
-void nouveau_hwmon_fini(struct drm_device *dev);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_hwsq.h b/drivers/gpu/drm/nouveau/nouveau_hwsq.h
new file mode 100644
index 0000000..6976875
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_hwsq.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2010 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
+ */
+
+#ifndef __NOUVEAU_HWSQ_H__
+#define __NOUVEAU_HWSQ_H__
+
+struct hwsq_ucode {
+ u8 data[0x200];
+ union {
+ u8 *u08;
+ u16 *u16;
+ u32 *u32;
+ } ptr;
+ u16 len;
+
+ u32 reg;
+ u32 val;
+};
+
+static inline void
+hwsq_init(struct hwsq_ucode *hwsq)
+{
+ hwsq->ptr.u08 = hwsq->data;
+ hwsq->reg = 0xffffffff;
+ hwsq->val = 0xffffffff;
+}
+
+static inline void
+hwsq_fini(struct hwsq_ucode *hwsq)
+{
+ do {
+ *hwsq->ptr.u08++ = 0x7f;
+ hwsq->len = hwsq->ptr.u08 - hwsq->data;
+ } while (hwsq->len & 3);
+ hwsq->ptr.u08 = hwsq->data;
+}
+
+static inline void
+hwsq_usec(struct hwsq_ucode *hwsq, u8 usec)
+{
+ u32 shift = 0;
+ while (usec & ~3) {
+ usec >>= 2;
+ shift++;
+ }
+
+ *hwsq->ptr.u08++ = (shift << 2) | usec;
+}
+
+static inline void
+hwsq_setf(struct hwsq_ucode *hwsq, u8 flag, int val)
+{
+ flag += 0x80;
+ if (val >= 0)
+ flag += 0x20;
+ if (val >= 1)
+ flag += 0x20;
+ *hwsq->ptr.u08++ = flag;
+}
+
+static inline void
+hwsq_op5f(struct hwsq_ucode *hwsq, u8 v0, u8 v1)
+{
+ *hwsq->ptr.u08++ = 0x5f;
+ *hwsq->ptr.u08++ = v0;
+ *hwsq->ptr.u08++ = v1;
+}
+
+static inline void
+hwsq_wr32(struct hwsq_ucode *hwsq, u32 reg, u32 val)
+{
+ if (val != hwsq->val) {
+ if ((val & 0xffff0000) == (hwsq->val & 0xffff0000)) {
+ *hwsq->ptr.u08++ = 0x42;
+ *hwsq->ptr.u16++ = (val & 0x0000ffff);
+ } else {
+ *hwsq->ptr.u08++ = 0xe2;
+ *hwsq->ptr.u32++ = val;
+ }
+
+ hwsq->val = val;
+ }
+
+ if ((reg & 0xffff0000) == (hwsq->reg & 0xffff0000)) {
+ *hwsq->ptr.u08++ = 0x40;
+ *hwsq->ptr.u16++ = (reg & 0x0000ffff);
+ } else {
+ *hwsq->ptr.u08++ = 0xe0;
+ *hwsq->ptr.u32++ = reg;
+ }
+ hwsq->reg = reg;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
new file mode 100644
index 0000000..4f6a572
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+ * Copyright 2005 Stephane Marchesin
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS AND/OR THEIR SUPPLIERS 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 <bskeggs@redhat.com>
+ * Roy Spliet <r.spliet@student.tudelft.nl>
+ */
+
+#include "nouveau_drm.h"
+#include "nouveau_pm.h"
+
+#include <subdev/fb.h>
+
+static int
+nv40_mem_timing_calc(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC);
+
+ /* XXX: I don't trust the -1's and +1's... they must come
+ * from somewhere! */
+ t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 |
+ 1 << 16 |
+ (e->tWTR + 2 + (t->tCWL - 1)) << 8 |
+ (e->tCL + 2 - (t->tCWL - 1));
+
+ t->reg[2] = 0x20200000 |
+ ((t->tCWL - 1) << 24 |
+ e->tRRD << 16 |
+ e->tRCDWR << 8 |
+ e->tRCDRD);
+
+ NV_DEBUG(drm, "Entry %d: 220: %08x %08x %08x\n", t->id,
+ t->reg[0], t->reg[1], t->reg[2]);
+ return 0;
+}
+
+static int
+nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct bit_entry P;
+ uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3;
+
+ if (bit_table(dev, 'P', &P))
+ return -EINVAL;
+
+ switch (min(len, (u8) 22)) {
+ case 22:
+ unk21 = e->tUNK_21;
+ case 21:
+ unk20 = e->tUNK_20;
+ case 20:
+ if (e->tCWL > 0)
+ t->tCWL = e->tCWL;
+ case 19:
+ unk18 = e->tUNK_18;
+ break;
+ }
+
+ t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC);
+
+ t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 |
+ max(unk18, (u8) 1) << 16 |
+ (e->tWTR + 2 + (t->tCWL - 1)) << 8;
+
+ t->reg[2] = ((t->tCWL - 1) << 24 |
+ e->tRRD << 16 |
+ e->tRCDWR << 8 |
+ e->tRCDRD);
+
+ t->reg[4] = e->tUNK_13 << 8 | e->tUNK_13;
+
+ t->reg[5] = (e->tRFC << 24 | max(e->tRCDRD, e->tRCDWR) << 16 | e->tRP);
+
+ t->reg[8] = boot->reg[8] & 0xffffff00;
+
+ if (P.version == 1) {
+ t->reg[1] |= (e->tCL + 2 - (t->tCWL - 1));
+
+ t->reg[3] = (0x14 + e->tCL) << 24 |
+ 0x16 << 16 |
+ (e->tCL - 1) << 8 |
+ (e->tCL - 1);
+
+ t->reg[4] |= boot->reg[4] & 0xffff0000;
+
+ t->reg[6] = (0x33 - t->tCWL) << 16 |
+ t->tCWL << 8 |
+ (0x2e + e->tCL - t->tCWL);
+
+ 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) {
+ t->reg[5] |= (e->tCL + 3) << 8;
+ t->reg[6] |= (t->tCWL - 2) << 8;
+ t->reg[8] |= (e->tCL - 4);
+ } else {
+ t->reg[5] |= (e->tCL + 2) << 8;
+ t->reg[6] |= t->tCWL << 8;
+ t->reg[8] |= (e->tCL - 2);
+ }
+ } else {
+ t->reg[1] |= (5 + e->tCL - (t->tCWL));
+
+ /* XXX: 0xb? 0x30? */
+ t->reg[3] = (0x30 + e->tCL) << 24 |
+ (boot->reg[3] & 0x00ff0000)|
+ (0xb + e->tCL) << 8 |
+ (e->tCL - 1);
+
+ t->reg[4] |= (unk20 << 24 | unk21 << 16);
+
+ /* XXX: +6? */
+ t->reg[5] |= (t->tCWL + 6) << 8;
+
+ t->reg[6] = (0x5a + e->tCL) << 16 |
+ (6 - e->tCL + t->tCWL) << 8 |
+ (0x50 + e->tCL - t->tCWL);
+
+ tmp7_3 = (boot->reg[7] & 0xff000000) >> 24;
+ t->reg[7] = (tmp7_3 << 24) |
+ ((tmp7_3 - 6 + e->tCL) << 16) |
+ 0x202;
+ }
+
+ NV_DEBUG(drm, "Entry %d: 220: %08x %08x %08x %08x\n", t->id,
+ t->reg[0], t->reg[1], t->reg[2], t->reg[3]);
+ NV_DEBUG(drm, " 230: %08x %08x %08x %08x\n",
+ t->reg[4], t->reg[5], t->reg[6], t->reg[7]);
+ NV_DEBUG(drm, " 240: %08x\n", t->reg[8]);
+ return 0;
+}
+
+static int
+nvc0_mem_timing_calc(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ if (e->tCWL > 0)
+ t->tCWL = e->tCWL;
+
+ t->reg[0] = (e->tRP << 24 | (e->tRAS & 0x7f) << 17 |
+ e->tRFC << 8 | e->tRC);
+
+ t->reg[1] = (boot->reg[1] & 0xff000000) |
+ (e->tRCDWR & 0x0f) << 20 |
+ (e->tRCDRD & 0x0f) << 14 |
+ (t->tCWL << 7) |
+ (e->tCL & 0x0f);
+
+ t->reg[2] = (boot->reg[2] & 0xff0000ff) |
+ e->tWR << 16 | e->tWTR << 8;
+
+ t->reg[3] = (e->tUNK_20 & 0x1f) << 9 |
+ (e->tUNK_21 & 0xf) << 5 |
+ (e->tUNK_13 & 0x1f);
+
+ t->reg[4] = (boot->reg[4] & 0xfff00fff) |
+ (e->tRRD&0x1f) << 15;
+
+ NV_DEBUG(drm, "Entry %d: 290: %08x %08x %08x %08x\n", t->id,
+ t->reg[0], t->reg[1], t->reg[2], t->reg[3]);
+ NV_DEBUG(drm, " 2a0: %08x\n", t->reg[4]);
+ return 0;
+}
+
+/**
+ * MR generation methods
+ */
+
+static int
+nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ t->drive_strength = 0;
+ if (len < 15) {
+ t->odt = boot->odt;
+ } else {
+ t->odt = e->RAM_FT1 & 0x07;
+ }
+
+ if (e->tCL >= NV_MEM_CL_DDR2_MAX) {
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ return -ERANGE;
+ }
+
+ if (e->tWR >= NV_MEM_WR_DDR2_MAX) {
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ return -ERANGE;
+ }
+
+ if (t->odt > 3) {
+ NV_WARN(drm, "(%u) Invalid odt value, assuming disabled: %x",
+ t->id, t->odt);
+ t->odt = 0;
+ }
+
+ t->mr[0] = (boot->mr[0] & 0x100f) |
+ (e->tCL) << 4 |
+ (e->tWR - 1) << 9;
+ t->mr[1] = (boot->mr[1] & 0x101fbb) |
+ (t->odt & 0x1) << 2 |
+ (t->odt & 0x2) << 5;
+
+ NV_DEBUG(drm, "(%u) MR: %08x", t->id, t->mr[0]);
+ return 0;
+}
+
+static const uint8_t nv_mem_wr_lut_ddr3[NV_MEM_WR_DDR3_MAX] = {
+ 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
+
+static int
+nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u8 cl = e->tCL - 4;
+
+ t->drive_strength = 0;
+ if (len < 15) {
+ t->odt = boot->odt;
+ } else {
+ t->odt = e->RAM_FT1 & 0x07;
+ }
+
+ if (e->tCL >= NV_MEM_CL_DDR3_MAX || e->tCL < 4) {
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ return -ERANGE;
+ }
+
+ if (e->tWR >= NV_MEM_WR_DDR3_MAX || e->tWR < 4) {
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ return -ERANGE;
+ }
+
+ if (e->tCWL < 5) {
+ NV_WARN(drm, "(%u) Invalid tCWL: %u", t->id, e->tCWL);
+ return -ERANGE;
+ }
+
+ t->mr[0] = (boot->mr[0] & 0x180b) |
+ /* CAS */
+ (cl & 0x7) << 4 |
+ (cl & 0x8) >> 1 |
+ (nv_mem_wr_lut_ddr3[e->tWR]) << 9;
+ t->mr[1] = (boot->mr[1] & 0x101dbb) |
+ (t->odt & 0x1) << 2 |
+ (t->odt & 0x2) << 5 |
+ (t->odt & 0x4) << 7;
+ t->mr[2] = (boot->mr[2] & 0x20ffb7) | (e->tCWL - 5) << 3;
+
+ NV_DEBUG(drm, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[2]);
+ return 0;
+}
+
+static const uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = {
+ 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11};
+static const uint8_t nv_mem_wr_lut_gddr3[NV_MEM_WR_GDDR3_MAX] = {
+ 0, 0, 0, 0, 0, 2, 3, 8, 9, 10, 11, 0, 0, 1, 1, 0, 3};
+
+static int
+nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ if (len < 15) {
+ t->drive_strength = boot->drive_strength;
+ t->odt = boot->odt;
+ } else {
+ t->drive_strength = (e->RAM_FT1 & 0x30) >> 4;
+ t->odt = e->RAM_FT1 & 0x07;
+ }
+
+ if (e->tCL >= NV_MEM_CL_GDDR3_MAX) {
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ return -ERANGE;
+ }
+
+ if (e->tWR >= NV_MEM_WR_GDDR3_MAX) {
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ return -ERANGE;
+ }
+
+ if (t->odt > 3) {
+ NV_WARN(drm, "(%u) Invalid odt value, assuming autocal: %x",
+ t->id, t->odt);
+ t->odt = 0;
+ }
+
+ t->mr[0] = (boot->mr[0] & 0xe0b) |
+ /* CAS */
+ ((nv_mem_cl_lut_gddr3[e->tCL] & 0x7) << 4) |
+ ((nv_mem_cl_lut_gddr3[e->tCL] & 0x8) >> 2);
+ t->mr[1] = (boot->mr[1] & 0x100f40) | t->drive_strength |
+ (t->odt << 2) |
+ (nv_mem_wr_lut_gddr3[e->tWR] & 0xf) << 4;
+ t->mr[2] = boot->mr[2];
+
+ NV_DEBUG(drm, "(%u) MR: %08x %08x %08x", t->id,
+ t->mr[0], t->mr[1], t->mr[2]);
+ return 0;
+}
+
+static int
+nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ if (len < 15) {
+ t->drive_strength = boot->drive_strength;
+ t->odt = boot->odt;
+ } else {
+ t->drive_strength = (e->RAM_FT1 & 0x30) >> 4;
+ t->odt = e->RAM_FT1 & 0x03;
+ }
+
+ if (e->tCL >= NV_MEM_CL_GDDR5_MAX) {
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ return -ERANGE;
+ }
+
+ if (e->tWR >= NV_MEM_WR_GDDR5_MAX) {
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ return -ERANGE;
+ }
+
+ if (t->odt > 3) {
+ NV_WARN(drm, "(%u) Invalid odt value, assuming autocal: %x",
+ t->id, t->odt);
+ t->odt = 0;
+ }
+
+ t->mr[0] = (boot->mr[0] & 0x007) |
+ ((e->tCL - 5) << 3) |
+ ((e->tWR - 4) << 8);
+ t->mr[1] = (boot->mr[1] & 0x1007f0) |
+ t->drive_strength |
+ (t->odt << 2);
+
+ NV_DEBUG(drm, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]);
+ return 0;
+}
+
+int
+nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_memtiming *boot = &pm->boot.timing;
+ struct nouveau_pm_tbl_entry *e;
+ u8 ver, len, *ptr, *ramcfg;
+ int ret;
+
+ ptr = nouveau_perf_timing(dev, freq, &ver, &len);
+ if (!ptr || ptr[0] == 0x00) {
+ *t = *boot;
+ return 0;
+ }
+ e = (struct nouveau_pm_tbl_entry *)ptr;
+
+ t->tCWL = boot->tCWL;
+
+ switch (device->card_type) {
+ case NV_40:
+ ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t);
+ break;
+ case NV_50:
+ ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t);
+ break;
+ case NV_C0:
+ case NV_D0:
+ ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t);
+ break;
+ default:
+ ret = -ENODEV;
+ break;
+ }
+
+ switch (pfb->ram->type * !ret) {
+ case NV_MEM_TYPE_GDDR3:
+ ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
+ break;
+ case NV_MEM_TYPE_GDDR5:
+ ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t);
+ break;
+ case NV_MEM_TYPE_DDR2:
+ ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t);
+ break;
+ case NV_MEM_TYPE_DDR3:
+ ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ ramcfg = nouveau_perf_ramcfg(dev, freq, &ver, &len);
+ if (ramcfg) {
+ int dll_off;
+
+ if (ver == 0x00)
+ dll_off = !!(ramcfg[3] & 0x04);
+ else
+ dll_off = !!(ramcfg[2] & 0x40);
+
+ switch (pfb->ram->type) {
+ case NV_MEM_TYPE_GDDR3:
+ t->mr[1] &= ~0x00000040;
+ t->mr[1] |= 0x00000040 * dll_off;
+ break;
+ default:
+ t->mr[1] &= ~0x00000001;
+ t->mr[1] |= 0x00000001 * dll_off;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void
+nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ u32 timing_base, timing_regs, mr_base;
+ int i;
+
+ if (device->card_type >= 0xC0) {
+ timing_base = 0x10f290;
+ mr_base = 0x10f300;
+ } else {
+ timing_base = 0x100220;
+ mr_base = 0x1002c0;
+ }
+
+ t->id = -1;
+
+ switch (device->card_type) {
+ case NV_50:
+ timing_regs = 9;
+ break;
+ case NV_C0:
+ case NV_D0:
+ timing_regs = 5;
+ break;
+ case NV_30:
+ case NV_40:
+ timing_regs = 3;
+ break;
+ default:
+ timing_regs = 0;
+ return;
+ }
+ for(i = 0; i < timing_regs; i++)
+ t->reg[i] = nv_rd32(device, timing_base + (0x04 * i));
+
+ t->tCWL = 0;
+ if (device->card_type < NV_C0) {
+ t->tCWL = ((nv_rd32(device, 0x100228) & 0x0f000000) >> 24) + 1;
+ } else if (device->card_type <= NV_D0) {
+ t->tCWL = ((nv_rd32(device, 0x10f294) & 0x00000f80) >> 7);
+ }
+
+ t->mr[0] = nv_rd32(device, mr_base);
+ t->mr[1] = nv_rd32(device, mr_base + 0x04);
+ t->mr[2] = nv_rd32(device, mr_base + 0x20);
+ t->mr[3] = nv_rd32(device, mr_base + 0x24);
+
+ t->odt = 0;
+ t->drive_strength = 0;
+
+ switch (pfb->ram->type) {
+ case NV_MEM_TYPE_DDR3:
+ t->odt |= (t->mr[1] & 0x200) >> 7;
+ case NV_MEM_TYPE_DDR2:
+ t->odt |= (t->mr[1] & 0x04) >> 2 |
+ (t->mr[1] & 0x40) >> 5;
+ break;
+ case NV_MEM_TYPE_GDDR3:
+ case NV_MEM_TYPE_GDDR5:
+ t->drive_strength = t->mr[1] & 0x03;
+ t->odt = (t->mr[1] & 0x0c) >> 2;
+ break;
+ default:
+ break;
+ }
+}
+
+int
+nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
+ struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_drm *drm = nouveau_drm(exec->dev);
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct nouveau_pm_memtiming *info = &perflvl->timing;
+ u32 tMRD = 1000, tCKSRE = 0, tCKSRX = 0, tXS = 0, tDLLK = 0;
+ u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] };
+ u32 mr1_dlloff;
+
+ switch (pfb->ram->type) {
+ case NV_MEM_TYPE_DDR2:
+ tDLLK = 2000;
+ mr1_dlloff = 0x00000001;
+ break;
+ case NV_MEM_TYPE_DDR3:
+ tDLLK = 12000;
+ tCKSRE = 2000;
+ tXS = 1000;
+ mr1_dlloff = 0x00000001;
+ break;
+ case NV_MEM_TYPE_GDDR3:
+ tDLLK = 40000;
+ mr1_dlloff = 0x00000040;
+ break;
+ default:
+ NV_ERROR(drm, "cannot reclock unsupported memtype\n");
+ return -ENODEV;
+ }
+
+ /* fetch current MRs */
+ switch (pfb->ram->type) {
+ case NV_MEM_TYPE_GDDR3:
+ case NV_MEM_TYPE_DDR3:
+ mr[2] = exec->mrg(exec, 2);
+ default:
+ mr[1] = exec->mrg(exec, 1);
+ mr[0] = exec->mrg(exec, 0);
+ break;
+ }
+
+ /* DLL 'on' -> DLL 'off' mode, disable before entering self-refresh */
+ if (!(mr[1] & mr1_dlloff) && (info->mr[1] & mr1_dlloff)) {
+ exec->precharge(exec);
+ exec->mrs (exec, 1, mr[1] | mr1_dlloff);
+ exec->wait(exec, tMRD);
+ }
+
+ /* enter self-refresh mode */
+ exec->precharge(exec);
+ exec->refresh(exec);
+ exec->refresh(exec);
+ exec->refresh_auto(exec, false);
+ exec->refresh_self(exec, true);
+ exec->wait(exec, tCKSRE);
+
+ /* modify input clock frequency */
+ exec->clock_set(exec);
+
+ /* exit self-refresh mode */
+ exec->wait(exec, tCKSRX);
+ exec->precharge(exec);
+ exec->refresh_self(exec, false);
+ exec->refresh_auto(exec, true);
+ exec->wait(exec, tXS);
+ exec->wait(exec, tXS);
+
+ /* update MRs */
+ if (mr[2] != info->mr[2]) {
+ exec->mrs (exec, 2, info->mr[2]);
+ exec->wait(exec, tMRD);
+ }
+
+ if (mr[1] != info->mr[1]) {
+ /* need to keep DLL off until later, at least on GDDR3 */
+ exec->mrs (exec, 1, info->mr[1] | (mr[1] & mr1_dlloff));
+ exec->wait(exec, tMRD);
+ }
+
+ if (mr[0] != info->mr[0]) {
+ exec->mrs (exec, 0, info->mr[0]);
+ exec->wait(exec, tMRD);
+ }
+
+ /* update PFB timing registers */
+ exec->timing_set(exec);
+
+ /* DLL (enable + ) reset */
+ if (!(info->mr[1] & mr1_dlloff)) {
+ if (mr[1] & mr1_dlloff) {
+ exec->mrs (exec, 1, info->mr[1]);
+ exec->wait(exec, tMRD);
+ }
+ exec->mrs (exec, 0, info->mr[0] | 0x00000100);
+ exec->wait(exec, tMRD);
+ exec->mrs (exec, 0, info->mr[0] | 0x00000000);
+ exec->wait(exec, tMRD);
+ exec->wait(exec, tDLLK);
+ if (pfb->ram->type == NV_MEM_TYPE_GDDR3)
+ exec->precharge(exec);
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c
new file mode 100644
index 0000000..4fe883c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2010 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 <drm/drmP.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+#include "nouveau_pm.h"
+
+static u8 *
+nouveau_perf_table(struct drm_device *dev, u8 *ver)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
+ struct bit_entry P;
+
+ if (!bit_table(dev, 'P', &P) && P.version && P.version <= 2) {
+ u8 *perf = ROMPTR(dev, P.data[0]);
+ if (perf) {
+ *ver = perf[0];
+ return perf;
+ }
+ }
+
+ if (bios->type == NVBIOS_BMP) {
+ if (bios->data[bios->offset + 6] >= 0x25) {
+ u8 *perf = ROMPTR(dev, bios->data[bios->offset + 0x94]);
+ if (perf) {
+ *ver = perf[1];
+ return perf;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static u8 *
+nouveau_perf_entry(struct drm_device *dev, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ u8 *perf = nouveau_perf_table(dev, ver);
+ if (perf) {
+ if (*ver >= 0x12 && *ver < 0x20 && idx < perf[2]) {
+ *hdr = perf[3];
+ *cnt = 0;
+ *len = 0;
+ return perf + perf[0] + idx * perf[3];
+ } else
+ if (*ver >= 0x20 && *ver < 0x40 && idx < perf[2]) {
+ *hdr = perf[3];
+ *cnt = perf[4];
+ *len = perf[5];
+ return perf + perf[1] + idx * (*hdr + (*cnt * *len));
+ } else
+ if (*ver >= 0x40 && *ver < 0x41 && idx < perf[5]) {
+ *hdr = perf[2];
+ *cnt = perf[4];
+ *len = perf[3];
+ return perf + perf[1] + idx * (*hdr + (*cnt * *len));
+ }
+ }
+ return NULL;
+}
+
+u8 *
+nouveau_perf_rammap(struct drm_device *dev, u32 freq,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct bit_entry P;
+ u8 *perf, i = 0;
+
+ if (!bit_table(dev, 'P', &P) && P.version == 2) {
+ u8 *rammap = ROMPTR(dev, P.data[4]);
+ if (rammap) {
+ u8 *ramcfg = rammap + rammap[1];
+
+ *ver = rammap[0];
+ *hdr = rammap[2];
+ *cnt = rammap[4];
+ *len = rammap[3];
+
+ freq /= 1000;
+ for (i = 0; i < rammap[5]; i++) {
+ if (freq >= ROM16(ramcfg[0]) &&
+ freq <= ROM16(ramcfg[2]))
+ return ramcfg;
+
+ ramcfg += *hdr + (*cnt * *len);
+ }
+ }
+
+ return NULL;
+ }
+
+ if (nv_device(drm->device)->chipset == 0x49 ||
+ nv_device(drm->device)->chipset == 0x4b)
+ freq /= 2;
+
+ while ((perf = nouveau_perf_entry(dev, i++, ver, hdr, cnt, len))) {
+ if (*ver >= 0x20 && *ver < 0x25) {
+ if (perf[0] != 0xff && freq <= ROM16(perf[11]) * 1000)
+ break;
+ } else
+ if (*ver >= 0x25 && *ver < 0x40) {
+ if (perf[0] != 0xff && freq <= ROM16(perf[12]) * 1000)
+ break;
+ }
+ }
+
+ if (perf) {
+ u8 *ramcfg = perf + *hdr;
+ *ver = 0x00;
+ *hdr = 0;
+ return ramcfg;
+ }
+
+ return NULL;
+}
+
+u8 *
+nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
+ u8 strap, hdr, cnt;
+ u8 *rammap;
+
+ strap = (nv_rd32(device, 0x101000) & 0x0000003c) >> 2;
+ if (bios->ram_restrict_tbl_ptr)
+ strap = bios->data[bios->ram_restrict_tbl_ptr + strap];
+
+ rammap = nouveau_perf_rammap(dev, freq, ver, &hdr, &cnt, len);
+ if (rammap && strap < cnt)
+ return rammap + hdr + (strap * *len);
+
+ return NULL;
+}
+
+u8 *
+nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
+ struct bit_entry P;
+ u8 *perf, *timing = NULL;
+ u8 i = 0, hdr, cnt;
+
+ if (bios->type == NVBIOS_BMP) {
+ while ((perf = nouveau_perf_entry(dev, i++, ver, &hdr, &cnt,
+ len)) && *ver == 0x15) {
+ if (freq <= ROM32(perf[5]) * 20) {
+ *ver = 0x00;
+ *len = 14;
+ return perf + 41;
+ }
+ }
+ return NULL;
+ }
+
+ if (!bit_table(dev, 'P', &P)) {
+ if (P.version == 1)
+ timing = ROMPTR(dev, P.data[4]);
+ else
+ if (P.version == 2)
+ timing = ROMPTR(dev, P.data[8]);
+ }
+
+ if (timing && timing[0] == 0x10) {
+ u8 *ramcfg = nouveau_perf_ramcfg(dev, freq, ver, len);
+ if (ramcfg && ramcfg[1] < timing[2]) {
+ *ver = timing[0];
+ *len = timing[3];
+ return timing + timing[1] + (ramcfg[1] * timing[3]);
+ }
+ }
+
+ return NULL;
+}
+
+static void
+legacy_perf_init(struct drm_device *dev)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ char *perf, *entry, *bmp = &bios->data[bios->offset];
+ int headerlen, use_straps;
+
+ if (bmp[5] < 0x5 || bmp[6] < 0x14) {
+ NV_DEBUG(drm, "BMP version too old for perf\n");
+ return;
+ }
+
+ perf = ROMPTR(dev, bmp[0x73]);
+ if (!perf) {
+ NV_DEBUG(drm, "No memclock table pointer found.\n");
+ return;
+ }
+
+ switch (perf[0]) {
+ case 0x12:
+ case 0x14:
+ case 0x18:
+ use_straps = 0;
+ headerlen = 1;
+ break;
+ case 0x01:
+ use_straps = perf[1] & 1;
+ headerlen = (use_straps ? 8 : 2);
+ break;
+ default:
+ NV_WARN(drm, "Unknown memclock table version %x.\n", perf[0]);
+ return;
+ }
+
+ entry = perf + headerlen;
+ if (use_straps)
+ entry += (nv_rd32(device, NV_PEXTDEV_BOOT_0) & 0x3c) >> 1;
+
+ sprintf(pm->perflvl[0].name, "performance_level_0");
+ pm->perflvl[0].memory = ROM16(entry[0]) * 20;
+ pm->nr_perflvl = 1;
+}
+
+static void
+nouveau_perf_voltage(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct bit_entry P;
+ u8 *vmap;
+ int id;
+
+ id = perflvl->volt_min;
+ perflvl->volt_min = 0;
+
+ /* boards using voltage table version <0x40 store the voltage
+ * level directly in the perflvl entry as a multiple of 10mV
+ */
+ if (drm->pm->voltage.version < 0x40) {
+ perflvl->volt_min = id * 10000;
+ perflvl->volt_max = perflvl->volt_min;
+ return;
+ }
+
+ /* on newer ones, the perflvl stores an index into yet another
+ * vbios table containing a min/max voltage value for the perflvl
+ */
+ if (bit_table(dev, 'P', &P) || P.version != 2 || P.length < 34) {
+ NV_DEBUG(drm, "where's our volt map table ptr? %d %d\n",
+ P.version, P.length);
+ return;
+ }
+
+ vmap = ROMPTR(dev, P.data[32]);
+ if (!vmap) {
+ NV_DEBUG(drm, "volt map table pointer invalid\n");
+ return;
+ }
+
+ if (id < vmap[3]) {
+ vmap += vmap[1] + (vmap[2] * id);
+ perflvl->volt_min = ROM32(vmap[0]);
+ perflvl->volt_max = ROM32(vmap[4]);
+ }
+}
+
+void
+nouveau_perf_init(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nvbios *bios = &drm->vbios;
+ u8 *perf, ver, hdr, cnt, len;
+ int ret, vid, i = -1;
+
+ if (bios->type == NVBIOS_BMP && bios->data[bios->offset + 6] < 0x25) {
+ legacy_perf_init(dev);
+ return;
+ }
+
+ perf = nouveau_perf_table(dev, &ver);
+
+ while ((perf = nouveau_perf_entry(dev, ++i, &ver, &hdr, &cnt, &len))) {
+ struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
+
+ if (perf[0] == 0xff)
+ continue;
+
+ switch (ver) {
+ case 0x12:
+ case 0x13:
+ case 0x15:
+ perflvl->fanspeed = perf[55];
+ if (hdr > 56)
+ perflvl->volt_min = perf[56];
+ perflvl->core = ROM32(perf[1]) * 10;
+ perflvl->memory = ROM32(perf[5]) * 20;
+ break;
+ case 0x21:
+ case 0x23:
+ case 0x24:
+ perflvl->fanspeed = perf[4];
+ perflvl->volt_min = perf[5];
+ perflvl->shader = ROM16(perf[6]) * 1000;
+ perflvl->core = perflvl->shader;
+ perflvl->core += (signed char)perf[8] * 1000;
+ if (nv_device(drm->device)->chipset == 0x49 ||
+ nv_device(drm->device)->chipset == 0x4b)
+ perflvl->memory = ROM16(perf[11]) * 1000;
+ else
+ perflvl->memory = ROM16(perf[11]) * 2000;
+ break;
+ case 0x25:
+ perflvl->fanspeed = perf[4];
+ perflvl->volt_min = perf[5];
+ perflvl->core = ROM16(perf[6]) * 1000;
+ perflvl->shader = ROM16(perf[10]) * 1000;
+ perflvl->memory = ROM16(perf[12]) * 1000;
+ break;
+ case 0x30:
+ perflvl->memscript = ROM16(perf[2]);
+ case 0x35:
+ perflvl->fanspeed = perf[6];
+ perflvl->volt_min = perf[7];
+ perflvl->core = ROM16(perf[8]) * 1000;
+ perflvl->shader = ROM16(perf[10]) * 1000;
+ perflvl->memory = ROM16(perf[12]) * 1000;
+ perflvl->vdec = ROM16(perf[16]) * 1000;
+ perflvl->dom6 = ROM16(perf[20]) * 1000;
+ break;
+ case 0x40:
+#define subent(n) ((ROM16(perf[hdr + (n) * len]) & 0xfff) * 1000)
+ perflvl->fanspeed = 0; /*XXX*/
+ perflvl->volt_min = perf[2];
+ if (nv_device(drm->device)->card_type == NV_50) {
+ perflvl->core = subent(0);
+ perflvl->shader = subent(1);
+ perflvl->memory = subent(2);
+ perflvl->vdec = subent(3);
+ perflvl->unka0 = subent(4);
+ } else {
+ perflvl->hub06 = subent(0);
+ perflvl->hub01 = subent(1);
+ perflvl->copy = subent(2);
+ perflvl->shader = subent(3);
+ perflvl->rop = subent(4);
+ perflvl->memory = subent(5);
+ perflvl->vdec = subent(6);
+ perflvl->daemon = subent(10);
+ perflvl->hub07 = subent(11);
+ perflvl->core = perflvl->shader / 2;
+ }
+ break;
+ }
+
+ /* make sure vid is valid */
+ nouveau_perf_voltage(dev, perflvl);
+ if (pm->voltage.supported && perflvl->volt_min) {
+ vid = nouveau_volt_vid_lookup(dev, perflvl->volt_min);
+ if (vid < 0) {
+ NV_DEBUG(drm, "perflvl %d, bad vid\n", i);
+ continue;
+ }
+ }
+
+ /* get the corresponding memory timings */
+ ret = nouveau_mem_timing_calc(dev, perflvl->memory,
+ &perflvl->timing);
+ if (ret) {
+ NV_DEBUG(drm, "perflvl %d, bad timing: %d\n", i, ret);
+ continue;
+ }
+
+ snprintf(perflvl->name, sizeof(perflvl->name),
+ "performance_level_%d", i);
+ perflvl->id = i;
+
+ snprintf(perflvl->profile.name, sizeof(perflvl->profile.name),
+ "%d", perflvl->id);
+ perflvl->profile.func = &nouveau_pm_static_profile_func;
+ list_add_tail(&perflvl->profile.head, &pm->profiles);
+
+
+ pm->nr_perflvl++;
+ }
+}
+
+void
+nouveau_perf_fini(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 4aff04f..936b442 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -32,12 +32,369 @@
#include <drm/drmP.h>
#include "nouveau_drm.h"
-#include "nouveau_hwmon.h"
+#include "nouveau_pm.h"
#include <subdev/gpio.h>
#include <subdev/timer.h>
#include <subdev/therm.h>
+MODULE_PARM_DESC(perflvl, "Performance level (default: boot)");
+static char *nouveau_perflvl;
+module_param_named(perflvl, nouveau_perflvl, charp, 0400);
+
+MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)");
+static int nouveau_perflvl_wr;
+module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400);
+
+static int
+nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl,
+ struct nouveau_pm_level *a, struct nouveau_pm_level *b)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
+ int ret;
+
+ /*XXX: not on all boards, we should control based on temperature
+ * on recent boards.. or maybe on some other factor we don't
+ * know about?
+ */
+ if (therm && therm->fan_set &&
+ a->fanspeed && b->fanspeed && b->fanspeed > a->fanspeed) {
+ ret = therm->fan_set(therm, perflvl->fanspeed);
+ if (ret && ret != -ENODEV) {
+ NV_ERROR(drm, "fanspeed set failed: %d\n", ret);
+ }
+ }
+
+ if (pm->voltage.supported && pm->voltage_set) {
+ if (perflvl->volt_min && b->volt_min > a->volt_min) {
+ ret = pm->voltage_set(dev, perflvl->volt_min);
+ if (ret) {
+ NV_ERROR(drm, "voltage set failed: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ void *state;
+ int ret;
+
+ if (perflvl == pm->cur)
+ return 0;
+
+ ret = nouveau_pm_perflvl_aux(dev, perflvl, pm->cur, perflvl);
+ if (ret)
+ return ret;
+
+ state = pm->clocks_pre(dev, perflvl);
+ if (IS_ERR(state)) {
+ ret = PTR_ERR(state);
+ goto error;
+ }
+ ret = pm->clocks_set(dev, state);
+ if (ret)
+ goto error;
+
+ ret = nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur);
+ if (ret)
+ return ret;
+
+ pm->cur = perflvl;
+ return 0;
+
+error:
+ /* restore the fan speed and voltage before leaving */
+ nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur);
+ return ret;
+}
+
+void
+nouveau_pm_trigger(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_timer *ptimer = nouveau_timer(drm->device);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_profile *profile = NULL;
+ struct nouveau_pm_level *perflvl = NULL;
+ int ret;
+
+ /* select power profile based on current power source */
+ if (power_supply_is_system_supplied())
+ profile = pm->profile_ac;
+ else
+ profile = pm->profile_dc;
+
+ if (profile != pm->profile) {
+ pm->profile->func->fini(pm->profile);
+ pm->profile = profile;
+ pm->profile->func->init(pm->profile);
+ }
+
+ /* select performance level based on profile */
+ perflvl = profile->func->select(profile);
+
+ /* change perflvl, if necessary */
+ if (perflvl != pm->cur) {
+ u64 time0 = ptimer->read(ptimer);
+
+ NV_INFO(drm, "setting performance level: %d", perflvl->id);
+ ret = nouveau_pm_perflvl_set(dev, perflvl);
+ if (ret)
+ NV_INFO(drm, "> reclocking failed: %d\n\n", ret);
+
+ NV_INFO(drm, "> reclocking took %lluns\n\n",
+ ptimer->read(ptimer) - time0);
+ }
+}
+
+static struct nouveau_pm_profile *
+profile_find(struct drm_device *dev, const char *string)
+{
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_profile *profile;
+
+ list_for_each_entry(profile, &pm->profiles, head) {
+ if (!strncmp(profile->name, string, sizeof(profile->name)))
+ return profile;
+ }
+
+ return NULL;
+}
+
+static int
+nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
+{
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_profile *ac = NULL, *dc = NULL;
+ char string[16], *cur = string, *ptr;
+
+ /* safety precaution, for now */
+ if (nouveau_perflvl_wr != 7777)
+ return -EPERM;
+
+ strncpy(string, profile, sizeof(string));
+ string[sizeof(string) - 1] = 0;
+ if ((ptr = strchr(string, '\n')))
+ *ptr = '\0';
+
+ ptr = strsep(&cur, ",");
+ if (ptr)
+ ac = profile_find(dev, ptr);
+
+ ptr = strsep(&cur, ",");
+ if (ptr)
+ dc = profile_find(dev, ptr);
+ else
+ dc = ac;
+
+ if (ac == NULL || dc == NULL)
+ return -EINVAL;
+
+ pm->profile_ac = ac;
+ pm->profile_dc = dc;
+ nouveau_pm_trigger(dev);
+ return 0;
+}
+
+static void
+nouveau_pm_static_dummy(struct nouveau_pm_profile *profile)
+{
+}
+
+static struct nouveau_pm_level *
+nouveau_pm_static_select(struct nouveau_pm_profile *profile)
+{
+ return container_of(profile, struct nouveau_pm_level, profile);
+}
+
+const struct nouveau_pm_profile_func nouveau_pm_static_profile_func = {
+ .destroy = nouveau_pm_static_dummy,
+ .init = nouveau_pm_static_dummy,
+ .fini = nouveau_pm_static_dummy,
+ .select = nouveau_pm_static_select,
+};
+
+static int
+nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
+ int ret;
+
+ memset(perflvl, 0, sizeof(*perflvl));
+
+ if (pm->clocks_get) {
+ ret = pm->clocks_get(dev, perflvl);
+ if (ret)
+ return ret;
+ }
+
+ if (pm->voltage.supported && pm->voltage_get) {
+ ret = pm->voltage_get(dev);
+ if (ret > 0) {
+ perflvl->volt_min = ret;
+ perflvl->volt_max = ret;
+ }
+ }
+
+ if (therm && therm->fan_get) {
+ ret = therm->fan_get(therm);
+ if (ret >= 0)
+ perflvl->fanspeed = ret;
+ }
+
+ nouveau_mem_timing_read(dev, &perflvl->timing);
+ return 0;
+}
+
+static void
+nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
+{
+ char c[16], s[16], v[32], f[16], m[16];
+
+ c[0] = '\0';
+ if (perflvl->core)
+ snprintf(c, sizeof(c), " core %dMHz", perflvl->core / 1000);
+
+ s[0] = '\0';
+ if (perflvl->shader)
+ snprintf(s, sizeof(s), " shader %dMHz", perflvl->shader / 1000);
+
+ m[0] = '\0';
+ if (perflvl->memory)
+ snprintf(m, sizeof(m), " memory %dMHz", perflvl->memory / 1000);
+
+ v[0] = '\0';
+ if (perflvl->volt_min && perflvl->volt_min != perflvl->volt_max) {
+ snprintf(v, sizeof(v), " voltage %dmV-%dmV",
+ perflvl->volt_min / 1000, perflvl->volt_max / 1000);
+ } else
+ if (perflvl->volt_min) {
+ snprintf(v, sizeof(v), " voltage %dmV",
+ perflvl->volt_min / 1000);
+ }
+
+ f[0] = '\0';
+ if (perflvl->fanspeed)
+ snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed);
+
+ snprintf(ptr, len, "%s%s%s%s%s\n", c, s, m, v, f);
+}
+
+static ssize_t
+nouveau_pm_get_perflvl_info(struct device *d,
+ struct device_attribute *a, char *buf)
+{
+ struct nouveau_pm_level *perflvl =
+ container_of(a, struct nouveau_pm_level, dev_attr);
+ char *ptr = buf;
+ int len = PAGE_SIZE;
+
+ snprintf(ptr, len, "%d:", perflvl->id);
+ ptr += strlen(buf);
+ len -= strlen(buf);
+
+ nouveau_pm_perflvl_info(perflvl, ptr, len);
+ return strlen(buf);
+}
+
+static ssize_t
+nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf)
+{
+ struct drm_device *dev = pci_get_drvdata(to_pci_dev(d));
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_level cur;
+ int len = PAGE_SIZE, ret;
+ char *ptr = buf;
+
+ snprintf(ptr, len, "profile: %s, %s\nc:",
+ pm->profile_ac->name, pm->profile_dc->name);
+ ptr += strlen(buf);
+ len -= strlen(buf);
+
+ ret = nouveau_pm_perflvl_get(dev, &cur);
+ if (ret == 0)
+ nouveau_pm_perflvl_info(&cur, ptr, len);
+ return strlen(buf);
+}
+
+static ssize_t
+nouveau_pm_set_perflvl(struct device *d, struct device_attribute *a,
+ const char *buf, size_t count)
+{
+ struct drm_device *dev = pci_get_drvdata(to_pci_dev(d));
+ int ret;
+
+ ret = nouveau_pm_profile_set(dev, buf);
+ if (ret)
+ return ret;
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR,
+ nouveau_pm_get_perflvl, nouveau_pm_set_perflvl);
+
+static int
+nouveau_sysfs_init(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct device *d = &dev->pdev->dev;
+ int ret, i;
+
+ ret = device_create_file(d, &dev_attr_performance_level);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < pm->nr_perflvl; i++) {
+ struct nouveau_pm_level *perflvl = &pm->perflvl[i];
+
+ perflvl->dev_attr.attr.name = perflvl->name;
+ perflvl->dev_attr.attr.mode = S_IRUGO;
+ perflvl->dev_attr.show = nouveau_pm_get_perflvl_info;
+ perflvl->dev_attr.store = NULL;
+ sysfs_attr_init(&perflvl->dev_attr.attr);
+
+ ret = device_create_file(d, &perflvl->dev_attr);
+ if (ret) {
+ NV_ERROR(drm, "failed pervlvl %d sysfs: %d\n",
+ perflvl->id, i);
+ perflvl->dev_attr.attr.name = NULL;
+ nouveau_pm_fini(dev);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void
+nouveau_sysfs_fini(struct drm_device *dev)
+{
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct device *d = &dev->pdev->dev;
+ int i;
+
+ device_remove_file(d, &dev_attr_performance_level);
+ for (i = 0; i < pm->nr_perflvl; i++) {
+ struct nouveau_pm_level *pl = &pm->perflvl[i];
+
+ if (!pl->dev_attr.attr.name)
+ break;
+
+ device_remove_file(d, &pl->dev_attr);
+ }
+}
+
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
static ssize_t
nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
@@ -421,6 +778,9 @@ nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a,
int ret = -ENODEV;
long value;
+ if (nouveau_perflvl_wr != 7777)
+ return -EPERM;
+
if (kstrtol(buf, 10, &value) == -EINVAL)
return -EINVAL;
@@ -559,21 +919,17 @@ static const struct attribute_group hwmon_pwm_fan_attrgroup = {
};
#endif
-int
+static int
nouveau_hwmon_init(struct drm_device *dev)
{
+ struct nouveau_pm *pm = nouveau_pm(dev);
+
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_therm *therm = nouveau_therm(drm->device);
- struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
- hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
- if (!hwmon)
- return -ENOMEM;
- hwmon->dev = dev;
-
if (!therm || !therm->temp_get || !therm->attr_get || !therm->attr_set)
return -ENODEV;
@@ -620,36 +976,199 @@ nouveau_hwmon_init(struct drm_device *dev)
goto error;
}
- hwmon->hwmon = hwmon_dev;
+ pm->hwmon = hwmon_dev;
return 0;
error:
NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret);
hwmon_device_unregister(hwmon_dev);
- hwmon->hwmon = NULL;
+ pm->hwmon = NULL;
return ret;
#else
+ pm->hwmon = NULL;
return 0;
#endif
}
-void
+static void
nouveau_hwmon_fini(struct drm_device *dev)
{
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
- struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
- if (hwmon->hwmon) {
- sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_default_attrgroup);
- sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_temp_attrgroup);
- sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_pwm_fan_attrgroup);
- sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_fan_rpm_attrgroup);
+ if (pm->hwmon) {
+ sysfs_remove_group(&pm->hwmon->kobj, &hwmon_default_attrgroup);
+ sysfs_remove_group(&pm->hwmon->kobj, &hwmon_temp_attrgroup);
+ sysfs_remove_group(&pm->hwmon->kobj, &hwmon_pwm_fan_attrgroup);
+ sysfs_remove_group(&pm->hwmon->kobj, &hwmon_fan_rpm_attrgroup);
- hwmon_device_unregister(hwmon->hwmon);
+ hwmon_device_unregister(pm->hwmon);
}
+#endif
+}
+
+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
+static int
+nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data)
+{
+ struct nouveau_pm *pm = container_of(nb, struct nouveau_pm, acpi_nb);
+ struct nouveau_drm *drm = nouveau_drm(pm->dev);
+ struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
+
+ if (strcmp(entry->device_class, "ac_adapter") == 0) {
+ bool ac = power_supply_is_system_supplied();
- nouveau_drm(dev)->hwmon = NULL;
- kfree(hwmon);
+ NV_DEBUG(drm, "power supply changed: %s\n", ac ? "AC" : "DC");
+ nouveau_pm_trigger(pm->dev);
+ }
+
+ return NOTIFY_OK;
+}
#endif
+
+int
+nouveau_pm_init(struct drm_device *dev)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm;
+ char info[256];
+ int ret, i;
+
+ pm = drm->pm = kzalloc(sizeof(*pm), GFP_KERNEL);
+ if (!pm)
+ return -ENOMEM;
+
+ pm->dev = dev;
+
+ if (device->card_type < NV_40) {
+ pm->clocks_get = nv04_pm_clocks_get;
+ pm->clocks_pre = nv04_pm_clocks_pre;
+ pm->clocks_set = nv04_pm_clocks_set;
+ if (nouveau_gpio(drm->device)) {
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ }
+ } else
+ if (device->card_type < NV_50) {
+ pm->clocks_get = nv40_pm_clocks_get;
+ pm->clocks_pre = nv40_pm_clocks_pre;
+ pm->clocks_set = nv40_pm_clocks_set;
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ } else
+ if (device->card_type < NV_C0) {
+ if (device->chipset < 0xa3 ||
+ device->chipset == 0xaa ||
+ device->chipset == 0xac) {
+ pm->clocks_get = nv50_pm_clocks_get;
+ pm->clocks_pre = nv50_pm_clocks_pre;
+ pm->clocks_set = nv50_pm_clocks_set;
+ } else {
+ pm->clocks_get = nva3_pm_clocks_get;
+ pm->clocks_pre = nva3_pm_clocks_pre;
+ pm->clocks_set = nva3_pm_clocks_set;
+ }
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ } else
+ if (device->card_type < NV_E0) {
+ pm->clocks_get = nvc0_pm_clocks_get;
+ pm->clocks_pre = nvc0_pm_clocks_pre;
+ pm->clocks_set = nvc0_pm_clocks_set;
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ }
+
+
+ /* parse aux tables from vbios */
+ nouveau_volt_init(dev);
+
+ INIT_LIST_HEAD(&pm->profiles);
+
+ /* determine current ("boot") performance level */
+ ret = nouveau_pm_perflvl_get(dev, &pm->boot);
+ if (ret) {
+ NV_ERROR(drm, "failed to determine boot perflvl\n");
+ return ret;
+ }
+
+ strncpy(pm->boot.name, "boot", 4);
+ strncpy(pm->boot.profile.name, "boot", 4);
+ pm->boot.profile.func = &nouveau_pm_static_profile_func;
+
+ list_add(&pm->boot.profile.head, &pm->profiles);
+
+ pm->profile_ac = &pm->boot.profile;
+ pm->profile_dc = &pm->boot.profile;
+ pm->profile = &pm->boot.profile;
+ pm->cur = &pm->boot;
+
+ /* add performance levels from vbios */
+ nouveau_perf_init(dev);
+
+ /* display available performance levels */
+ NV_INFO(drm, "%d available performance level(s)\n", pm->nr_perflvl);
+ for (i = 0; i < pm->nr_perflvl; i++) {
+ nouveau_pm_perflvl_info(&pm->perflvl[i], info, sizeof(info));
+ NV_INFO(drm, "%d:%s", pm->perflvl[i].id, info);
+ }
+
+ nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info));
+ NV_INFO(drm, "c:%s", info);
+
+ /* switch performance levels now if requested */
+ if (nouveau_perflvl != NULL)
+ nouveau_pm_profile_set(dev, nouveau_perflvl);
+
+ nouveau_sysfs_init(dev);
+ nouveau_hwmon_init(dev);
+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
+ pm->acpi_nb.notifier_call = nouveau_pm_acpi_event;
+ register_acpi_notifier(&pm->acpi_nb);
+#endif
+
+ return 0;
+}
+
+void
+nouveau_pm_fini(struct drm_device *dev)
+{
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_profile *profile, *tmp;
+
+ list_for_each_entry_safe(profile, tmp, &pm->profiles, head) {
+ list_del(&profile->head);
+ profile->func->destroy(profile);
+ }
+
+ if (pm->cur != &pm->boot)
+ nouveau_pm_perflvl_set(dev, &pm->boot);
+
+ nouveau_perf_fini(dev);
+ nouveau_volt_fini(dev);
+
+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
+ unregister_acpi_notifier(&pm->acpi_nb);
+#endif
+ nouveau_hwmon_fini(dev);
+ nouveau_sysfs_fini(dev);
+
+ nouveau_drm(dev)->pm = NULL;
+ kfree(pm);
+}
+
+void
+nouveau_pm_resume(struct drm_device *dev)
+{
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_level *perflvl;
+
+ if (!pm->cur || pm->cur == &pm->boot)
+ return;
+
+ perflvl = pm->cur;
+ pm->cur = &pm->boot;
+ nouveau_pm_perflvl_set(dev, perflvl);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h
new file mode 100644
index 0000000..73b789c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2010 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
+ */
+
+#ifndef __NOUVEAU_PM_H__
+#define __NOUVEAU_PM_H__
+
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+
+struct nouveau_pm_voltage_level {
+ u32 voltage; /* microvolts */
+ u8 vid;
+};
+
+struct nouveau_pm_voltage {
+ bool supported;
+ u8 version;
+ u8 vid_mask;
+
+ struct nouveau_pm_voltage_level *level;
+ int nr_level;
+};
+
+/* Exclusive upper limits */
+#define NV_MEM_CL_DDR2_MAX 8
+#define NV_MEM_WR_DDR2_MAX 9
+#define NV_MEM_CL_DDR3_MAX 17
+#define NV_MEM_WR_DDR3_MAX 17
+#define NV_MEM_CL_GDDR3_MAX 16
+#define NV_MEM_WR_GDDR3_MAX 18
+#define NV_MEM_CL_GDDR5_MAX 21
+#define NV_MEM_WR_GDDR5_MAX 20
+
+struct nouveau_pm_memtiming {
+ int id;
+
+ u32 reg[9];
+ u32 mr[4];
+
+ u8 tCWL;
+
+ u8 odt;
+ u8 drive_strength;
+};
+
+struct nouveau_pm_tbl_header {
+ u8 version;
+ u8 header_len;
+ u8 entry_cnt;
+ u8 entry_len;
+};
+
+struct nouveau_pm_tbl_entry {
+ u8 tWR;
+ u8 tWTR;
+ u8 tCL;
+ u8 tRC;
+ u8 empty_4;
+ u8 tRFC; /* Byte 5 */
+ u8 empty_6;
+ u8 tRAS; /* Byte 7 */
+ u8 empty_8;
+ u8 tRP; /* Byte 9 */
+ u8 tRCDRD;
+ u8 tRCDWR;
+ u8 tRRD;
+ u8 tUNK_13;
+ u8 RAM_FT1; /* 14, a bitmask of random RAM features */
+ u8 empty_15;
+ u8 tUNK_16;
+ u8 empty_17;
+ u8 tUNK_18;
+ u8 tCWL;
+ u8 tUNK_20, tUNK_21;
+};
+
+struct nouveau_pm_profile;
+struct nouveau_pm_profile_func {
+ void (*destroy)(struct nouveau_pm_profile *);
+ void (*init)(struct nouveau_pm_profile *);
+ void (*fini)(struct nouveau_pm_profile *);
+ struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *);
+};
+
+struct nouveau_pm_profile {
+ const struct nouveau_pm_profile_func *func;
+ struct list_head head;
+ char name[8];
+};
+
+#define NOUVEAU_PM_MAX_LEVEL 8
+struct nouveau_pm_level {
+ struct nouveau_pm_profile profile;
+ struct device_attribute dev_attr;
+ char name[32];
+ int id;
+
+ struct nouveau_pm_memtiming timing;
+ u32 memory;
+ u16 memscript;
+
+ u32 core;
+ u32 shader;
+ u32 rop;
+ u32 copy;
+ u32 daemon;
+ u32 vdec;
+ u32 dom6;
+ u32 unka0; /* nva3:nvc0 */
+ u32 hub01; /* nvc0- */
+ u32 hub06; /* nvc0- */
+ u32 hub07; /* nvc0- */
+
+ u32 volt_min; /* microvolts */
+ u32 volt_max;
+ u8 fanspeed;
+};
+
+struct nouveau_pm_temp_sensor_constants {
+ u16 offset_constant;
+ s16 offset_mult;
+ s16 offset_div;
+ s16 slope_mult;
+ s16 slope_div;
+};
+
+struct nouveau_pm_threshold_temp {
+ s16 critical;
+ s16 down_clock;
+};
+
+struct nouveau_pm {
+ struct drm_device *dev;
+
+ struct nouveau_pm_voltage voltage;
+ struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
+ int nr_perflvl;
+ struct nouveau_pm_temp_sensor_constants sensor_constants;
+ struct nouveau_pm_threshold_temp threshold_temp;
+
+ struct nouveau_pm_profile *profile_ac;
+ struct nouveau_pm_profile *profile_dc;
+ struct nouveau_pm_profile *profile;
+ struct list_head profiles;
+
+ struct nouveau_pm_level boot;
+ struct nouveau_pm_level *cur;
+
+ struct device *hwmon;
+ struct notifier_block acpi_nb;
+
+ int (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
+ void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
+ int (*clocks_set)(struct drm_device *, void *);
+
+ int (*voltage_get)(struct drm_device *);
+ int (*voltage_set)(struct drm_device *, int voltage);
+};
+
+static inline struct nouveau_pm *
+nouveau_pm(struct drm_device *dev)
+{
+ return nouveau_drm(dev)->pm;
+}
+
+struct nouveau_mem_exec_func {
+ struct drm_device *dev;
+ void (*precharge)(struct nouveau_mem_exec_func *);
+ void (*refresh)(struct nouveau_mem_exec_func *);
+ void (*refresh_auto)(struct nouveau_mem_exec_func *, bool);
+ void (*refresh_self)(struct nouveau_mem_exec_func *, bool);
+ void (*wait)(struct nouveau_mem_exec_func *, u32 nsec);
+ u32 (*mrg)(struct nouveau_mem_exec_func *, int mr);
+ void (*mrs)(struct nouveau_mem_exec_func *, int mr, u32 data);
+ void (*clock_set)(struct nouveau_mem_exec_func *);
+ void (*timing_set)(struct nouveau_mem_exec_func *);
+ void *priv;
+};
+
+/* nouveau_mem.c */
+int nouveau_mem_exec(struct nouveau_mem_exec_func *,
+ struct nouveau_pm_level *);
+
+/* nouveau_pm.c */
+int nouveau_pm_init(struct drm_device *dev);
+void nouveau_pm_fini(struct drm_device *dev);
+void nouveau_pm_resume(struct drm_device *dev);
+extern const struct nouveau_pm_profile_func nouveau_pm_static_profile_func;
+void nouveau_pm_trigger(struct drm_device *dev);
+
+/* nouveau_volt.c */
+void nouveau_volt_init(struct drm_device *);
+void nouveau_volt_fini(struct drm_device *);
+int nouveau_volt_vid_lookup(struct drm_device *, int voltage);
+int nouveau_volt_lvl_lookup(struct drm_device *, int vid);
+int nouveau_voltage_gpio_get(struct drm_device *);
+int nouveau_voltage_gpio_set(struct drm_device *, int voltage);
+
+/* nouveau_perf.c */
+void nouveau_perf_init(struct drm_device *);
+void nouveau_perf_fini(struct drm_device *);
+u8 *nouveau_perf_rammap(struct drm_device *, u32 freq, u8 *ver,
+ u8 *hdr, u8 *cnt, u8 *len);
+u8 *nouveau_perf_ramcfg(struct drm_device *, u32 freq, u8 *ver, u8 *len);
+u8 *nouveau_perf_timing(struct drm_device *, u32 freq, u8 *ver, u8 *len);
+
+/* nouveau_mem.c */
+void nouveau_mem_timing_init(struct drm_device *);
+void nouveau_mem_timing_fini(struct drm_device *);
+
+/* nv04_pm.c */
+int nv04_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
+void *nv04_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
+int nv04_pm_clocks_set(struct drm_device *, void *);
+
+/* nv40_pm.c */
+int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
+void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
+int nv40_pm_clocks_set(struct drm_device *, void *);
+int nv40_pm_pwm_get(struct drm_device *, int, u32 *, u32 *);
+int nv40_pm_pwm_set(struct drm_device *, int, u32, u32);
+
+/* nv50_pm.c */
+int nv50_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
+void *nv50_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
+int nv50_pm_clocks_set(struct drm_device *, void *);
+int nv50_pm_pwm_get(struct drm_device *, int, u32 *, u32 *);
+int nv50_pm_pwm_set(struct drm_device *, int, u32, u32);
+
+/* nva3_pm.c */
+int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
+void *nva3_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
+int nva3_pm_clocks_set(struct drm_device *, void *);
+
+/* nvc0_pm.c */
+int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
+void *nvc0_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
+int nvc0_pm_clocks_set(struct drm_device *, void *);
+
+/* nouveau_mem.c */
+int nouveau_mem_timing_calc(struct drm_device *, u32 freq,
+ struct nouveau_pm_memtiming *);
+void nouveau_mem_timing_read(struct drm_device *,
+ struct nouveau_pm_memtiming *);
+
+static inline int
+nva3_calc_pll(struct drm_device *dev, struct nvbios_pll *pll, u32 freq,
+ int *N, int *fN, int *M, int *P)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_clock *clk = nouveau_clock(device);
+ struct nouveau_pll_vals pv;
+ int ret;
+
+ ret = clk->pll_calc(clk, pll, freq, &pv);
+ *N = pv.N1;
+ *M = pv.M1;
+ *P = pv.log2P;
+ return ret;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
index 51a2cb1..e90468d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -71,16 +71,14 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev,
return ERR_PTR(ret);
nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_GART;
-
- /* Initialize the embedded gem-object. We return a single gem-reference
- * to the caller, instead of a normal nouveau_bo ttm reference. */
- ret = drm_gem_object_init(dev, &nvbo->gem, nvbo->bo.mem.size);
- if (ret) {
+ nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size);
+ if (!nvbo->gem) {
nouveau_bo_ref(NULL, &nvbo);
return ERR_PTR(-ENOMEM);
}
- return &nvbo->gem;
+ nvbo->gem->driver_private = nvbo;
+ return nvbo->gem;
}
int nouveau_gem_prime_pin(struct drm_gem_object *obj)
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
deleted file mode 100644
index 89201a1..0000000
--- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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 <bskeggs@redhat.com>
- */
-
-#include "nouveau_sysfs.h"
-
-#include <core/object.h>
-#include <core/class.h>
-
-static inline struct drm_device *
-drm_device(struct device *d)
-{
- return pci_get_drvdata(to_pci_dev(d));
-}
-
-#define snappendf(p,r,f,a...) do { \
- snprintf(p, r, f, ##a); \
- r -= strlen(p); \
- p += strlen(p); \
-} while(0)
-
-static ssize_t
-nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b)
-{
- struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d));
- struct nv_control_pstate_info info;
- size_t cnt = PAGE_SIZE;
- char *buf = b;
- int ret, i;
-
- ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_INFO, &info, sizeof(info));
- if (ret)
- return ret;
-
- for (i = 0; i < info.count + 1; i++) {
- const s32 state = i < info.count ? i :
- NV_CONTROL_PSTATE_ATTR_STATE_CURRENT;
- struct nv_control_pstate_attr attr = {
- .state = state,
- .index = 0,
- };
-
- ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR,
- &attr, sizeof(attr));
- if (ret)
- return ret;
-
- if (i < info.count)
- snappendf(buf, cnt, "%02x:", attr.state);
- else
- snappendf(buf, cnt, "--:");
-
- attr.index = 0;
- do {
- attr.state = state;
- ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR,
- &attr, sizeof(attr));
- if (ret)
- return ret;
-
- snappendf(buf, cnt, " %s %d", attr.name, attr.min);
- if (attr.min != attr.max)
- snappendf(buf, cnt, "-%d", attr.max);
- snappendf(buf, cnt, " %s", attr.unit);
- } while (attr.index);
-
- if ((state >= 0 && info.pstate == state) ||
- (state < 0 && info.ustate < 0))
- snappendf(buf, cnt, " *");
- snappendf(buf, cnt, "\n");
- }
-
- return strlen(b);
-}
-
-static ssize_t
-nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a,
- const char *buf, size_t count)
-{
- struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d));
- struct nv_control_pstate_user args;
- long value, ret;
- char *tmp;
-
- if ((tmp = strchr(buf, '\n')))
- *tmp = '\0';
-
- if (!strcasecmp(buf, "none"))
- args.state = NV_CONTROL_PSTATE_USER_STATE_UNKNOWN;
- else
- if (!strcasecmp(buf, "auto"))
- args.state = NV_CONTROL_PSTATE_USER_STATE_PERFMON;
- else {
- ret = kstrtol(buf, 16, &value);
- if (ret)
- return ret;
- args.state = value;
- }
-
- ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_USER, &args, sizeof(args));
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(pstate, S_IRUGO | S_IWUSR,
- nouveau_sysfs_pstate_get, nouveau_sysfs_pstate_set);
-
-void
-nouveau_sysfs_fini(struct drm_device *dev)
-{
- struct nouveau_sysfs *sysfs = nouveau_sysfs(dev);
- struct nouveau_drm *drm = nouveau_drm(dev);
-
- if (sysfs->ctrl) {
- device_remove_file(&dev->pdev->dev, &dev_attr_pstate);
- nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL);
- }
-
- drm->sysfs = NULL;
- kfree(sysfs);
-}
-
-int
-nouveau_sysfs_init(struct drm_device *dev)
-{
- struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_sysfs *sysfs;
- int ret;
-
- sysfs = drm->sysfs = kzalloc(sizeof(*sysfs), GFP_KERNEL);
- if (!sysfs)
- return -ENOMEM;
-
- ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL,
- NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl);
- if (ret == 0)
- device_create_file(&dev->pdev->dev, &dev_attr_pstate);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.h b/drivers/gpu/drm/nouveau/nouveau_sysfs.h
deleted file mode 100644
index 74b47f1..0000000
--- a/drivers/gpu/drm/nouveau/nouveau_sysfs.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __NOUVEAU_SYSFS_H__
-#define __NOUVEAU_SYSFS_H__
-
-#include "nouveau_drm.h"
-
-struct nouveau_sysfs {
- struct nouveau_object *ctrl;
-};
-
-static inline struct nouveau_sysfs *
-nouveau_sysfs(struct drm_device *dev)
-{
- return nouveau_drm(dev)->sysfs;
-}
-
-int nouveau_sysfs_init(struct drm_device *);
-void nouveau_sysfs_fini(struct drm_device *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_volt.c b/drivers/gpu/drm/nouveau/nouveau_volt.c
new file mode 100644
index 0000000..9976414
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_volt.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2010 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 <drm/drmP.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_pm.h"
+
+#include <subdev/bios/gpio.h>
+#include <subdev/gpio.h>
+
+static const enum dcb_gpio_func_name vidtag[] = { 0x04, 0x05, 0x06, 0x1a, 0x73 };
+static int nr_vidtag = sizeof(vidtag) / sizeof(vidtag[0]);
+
+int
+nouveau_voltage_gpio_get(struct drm_device *dev)
+{
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(device);
+ u8 vid = 0;
+ int i;
+
+ for (i = 0; i < nr_vidtag; i++) {
+ if (!(volt->vid_mask & (1 << i)))
+ continue;
+
+ vid |= gpio->get(gpio, 0, vidtag[i], 0xff) << i;
+ }
+
+ return nouveau_volt_lvl_lookup(dev, vid);
+}
+
+int
+nouveau_voltage_gpio_set(struct drm_device *dev, int voltage)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(device);
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
+ int vid, i;
+
+ vid = nouveau_volt_vid_lookup(dev, voltage);
+ if (vid < 0)
+ return vid;
+
+ for (i = 0; i < nr_vidtag; i++) {
+ if (!(volt->vid_mask & (1 << i)))
+ continue;
+
+ gpio->set(gpio, 0, vidtag[i], 0xff, !!(vid & (1 << i)));
+ }
+
+ return 0;
+}
+
+int
+nouveau_volt_vid_lookup(struct drm_device *dev, int voltage)
+{
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
+ int i;
+
+ for (i = 0; i < volt->nr_level; i++) {
+ if (volt->level[i].voltage == voltage)
+ return volt->level[i].vid;
+ }
+
+ return -ENOENT;
+}
+
+int
+nouveau_volt_lvl_lookup(struct drm_device *dev, int vid)
+{
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
+ int i;
+
+ for (i = 0; i < volt->nr_level; i++) {
+ if (volt->level[i].vid == vid)
+ return volt->level[i].voltage;
+ }
+
+ return -ENOENT;
+}
+
+void
+nouveau_volt_init(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_pm_voltage *voltage = &pm->voltage;
+ struct nvbios *bios = &drm->vbios;
+ struct dcb_gpio_func func;
+ struct bit_entry P;
+ u8 *volt = NULL, *entry;
+ int i, headerlen, recordlen, entries, vidmask, vidshift;
+
+ if (bios->type == NVBIOS_BIT) {
+ if (bit_table(dev, 'P', &P))
+ return;
+
+ if (P.version == 1)
+ volt = ROMPTR(dev, P.data[16]);
+ else
+ if (P.version == 2)
+ volt = ROMPTR(dev, P.data[12]);
+ else {
+ NV_WARN(drm, "unknown volt for BIT P %d\n", P.version);
+ }
+ } else {
+ if (bios->data[bios->offset + 6] < 0x27) {
+ NV_DEBUG(drm, "BMP version too old for voltage\n");
+ return;
+ }
+
+ volt = ROMPTR(dev, bios->data[bios->offset + 0x98]);
+ }
+
+ if (!volt) {
+ NV_DEBUG(drm, "voltage table pointer invalid\n");
+ return;
+ }
+
+ switch (volt[0]) {
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ headerlen = 5;
+ recordlen = volt[1];
+ entries = volt[2];
+ vidshift = 0;
+ vidmask = volt[4];
+ break;
+ case 0x20:
+ headerlen = volt[1];
+ recordlen = volt[3];
+ entries = volt[2];
+ vidshift = 0; /* could be vidshift like 0x30? */
+ vidmask = volt[5];
+ break;
+ case 0x30:
+ headerlen = volt[1];
+ recordlen = volt[2];
+ entries = volt[3];
+ vidmask = volt[4];
+ /* no longer certain what volt[5] is, if it's related to
+ * the vid shift then it's definitely not a function of
+ * how many bits are set.
+ *
+ * after looking at a number of nva3+ vbios images, they
+ * all seem likely to have a static shift of 2.. lets
+ * go with that for now until proven otherwise.
+ */
+ vidshift = 2;
+ break;
+ case 0x40:
+ headerlen = volt[1];
+ recordlen = volt[2];
+ entries = volt[3]; /* not a clue what the entries are for.. */
+ vidmask = volt[11]; /* guess.. */
+ vidshift = 0;
+ break;
+ default:
+ NV_WARN(drm, "voltage table 0x%02x unknown\n", volt[0]);
+ return;
+ }
+
+ /* validate vid mask */
+ voltage->vid_mask = vidmask;
+ if (!voltage->vid_mask)
+ return;
+
+ i = 0;
+ while (vidmask) {
+ if (i > nr_vidtag) {
+ NV_DEBUG(drm, "vid bit %d unknown\n", i);
+ return;
+ }
+
+ if (gpio && gpio->find(gpio, 0, vidtag[i], 0xff, &func)) {
+ NV_DEBUG(drm, "vid bit %d has no gpio tag\n", i);
+ return;
+ }
+
+ vidmask >>= 1;
+ i++;
+ }
+
+ /* parse vbios entries into common format */
+ voltage->version = volt[0];
+ if (voltage->version < 0x40) {
+ voltage->nr_level = entries;
+ voltage->level =
+ kcalloc(entries, sizeof(*voltage->level), GFP_KERNEL);
+ if (!voltage->level)
+ return;
+
+ entry = volt + headerlen;
+ for (i = 0; i < entries; i++, entry += recordlen) {
+ voltage->level[i].voltage = entry[0] * 10000;
+ voltage->level[i].vid = entry[1] >> vidshift;
+ }
+ } else {
+ u32 volt_uv = ROM32(volt[4]);
+ s16 step_uv = ROM16(volt[8]);
+ u8 vid;
+
+ voltage->nr_level = voltage->vid_mask + 1;
+ voltage->level = kcalloc(voltage->nr_level,
+ sizeof(*voltage->level), GFP_KERNEL);
+ if (!voltage->level)
+ return;
+
+ for (vid = 0; vid <= voltage->vid_mask; vid++) {
+ voltage->level[vid].voltage = volt_uv;
+ voltage->level[vid].vid = vid;
+ volt_uv += step_uv;
+ }
+ }
+
+ voltage->supported = true;
+}
+
+void
+nouveau_volt_fini(struct drm_device *dev)
+{
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
+
+ kfree(volt->level);
+}
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
index 8fe32bb..77dcc9c 100644
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -255,12 +255,6 @@ nv04_fbcon_accel_init(struct fb_info *info)
OUT_RING(chan, NvCtxSurf2D);
BEGIN_NV04(chan, NvSubImageBlit, 0x02fc, 1);
OUT_RING(chan, 3);
- if (device->chipset >= 0x11 /*XXX: oclass == 0x009f*/) {
- BEGIN_NV04(chan, NvSubImageBlit, 0x0120, 3);
- OUT_RING(chan, 0);
- OUT_RING(chan, 1);
- OUT_RING(chan, 2);
- }
BEGIN_NV04(chan, NvSubGdiRect, 0x0000, 1);
OUT_RING(chan, NvGdiRect);
diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c
new file mode 100644
index 0000000..27afc0e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_pm.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2010 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 <drm/drmP.h>
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+#include "dispnv04/hw.h"
+#include "nouveau_pm.h"
+
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+
+int
+nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ int ret;
+
+ ret = nouveau_hw_get_clock(dev, PLL_CORE);
+ if (ret < 0)
+ return ret;
+ perflvl->core = ret;
+
+ ret = nouveau_hw_get_clock(dev, PLL_MEMORY);
+ if (ret < 0)
+ return ret;
+ perflvl->memory = ret;
+
+ return 0;
+}
+
+struct nv04_pm_clock {
+ struct nvbios_pll pll;
+ struct nouveau_pll_vals calc;
+};
+
+struct nv04_pm_state {
+ struct nv04_pm_clock core;
+ struct nv04_pm_clock memory;
+};
+
+static int
+calc_pll(struct drm_device *dev, u32 id, int khz, struct nv04_pm_clock *clk)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_clock *pclk = nouveau_clock(device);
+ int ret;
+
+ ret = nvbios_pll_parse(bios, id, &clk->pll);
+ if (ret)
+ return ret;
+
+ ret = pclk->pll_calc(pclk, &clk->pll, khz, &clk->calc);
+ if (!ret)
+ return -EINVAL;
+
+ return 0;
+}
+
+void *
+nv04_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nv04_pm_state *info;
+ int ret;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ ret = calc_pll(dev, PLL_CORE, perflvl->core, &info->core);
+ if (ret)
+ goto error;
+
+ if (perflvl->memory) {
+ ret = calc_pll(dev, PLL_MEMORY, perflvl->memory, &info->memory);
+ if (ret)
+ goto error;
+ }
+
+ return info;
+error:
+ kfree(info);
+ return ERR_PTR(ret);
+}
+
+static void
+prog_pll(struct drm_device *dev, struct nv04_pm_clock *clk)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_clock *pclk = nouveau_clock(device);
+ u32 reg = clk->pll.reg;
+
+ /* thank the insane nouveau_hw_setpll() interface for this */
+ if (device->card_type >= NV_40)
+ reg += 4;
+
+ pclk->pll_prog(pclk, reg, &clk->calc);
+}
+
+int
+nv04_pm_clocks_set(struct drm_device *dev, void *pre_state)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_timer *ptimer = nouveau_timer(device);
+ struct nv04_pm_state *state = pre_state;
+
+ prog_pll(dev, &state->core);
+
+ if (state->memory.pll.reg) {
+ prog_pll(dev, &state->memory);
+ if (device->card_type < NV_30) {
+ if (device->card_type == NV_20)
+ nv_mask(device, 0x1002c4, 0, 1 << 20);
+
+ /* Reset the DLLs */
+ nv_mask(device, 0x1002c0, 0, 1 << 8);
+ }
+ }
+
+ nv_ofuncs(ptimer)->init(nv_object(ptimer));
+
+ kfree(state);
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c
new file mode 100644
index 0000000..625f80d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv40_pm.c
@@ -0,0 +1,353 @@
+/*
+ * 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
+ */
+
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
+#include "nouveau_bios.h"
+#include "nouveau_pm.h"
+#include "dispnv04/hw.h"
+
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+
+#include <engine/fifo.h>
+
+#define min2(a,b) ((a) < (b) ? (a) : (b))
+
+static u32
+read_pll_1(struct drm_device *dev, u32 reg)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, reg + 0x00);
+ int P = (ctrl & 0x00070000) >> 16;
+ int N = (ctrl & 0x0000ff00) >> 8;
+ int M = (ctrl & 0x000000ff) >> 0;
+ u32 ref = 27000, clk = 0;
+
+ if (ctrl & 0x80000000)
+ clk = ref * N / M;
+
+ return clk >> P;
+}
+
+static u32
+read_pll_2(struct drm_device *dev, u32 reg)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, reg + 0x00);
+ u32 coef = nv_rd32(device, reg + 0x04);
+ int N2 = (coef & 0xff000000) >> 24;
+ int M2 = (coef & 0x00ff0000) >> 16;
+ int N1 = (coef & 0x0000ff00) >> 8;
+ int M1 = (coef & 0x000000ff) >> 0;
+ int P = (ctrl & 0x00070000) >> 16;
+ u32 ref = 27000, clk = 0;
+
+ if ((ctrl & 0x80000000) && M1) {
+ clk = ref * N1 / M1;
+ if ((ctrl & 0x40000100) == 0x40000000) {
+ if (M2)
+ clk = clk * N2 / M2;
+ else
+ clk = 0;
+ }
+ }
+
+ return clk >> P;
+}
+
+static u32
+read_clk(struct drm_device *dev, u32 src)
+{
+ switch (src) {
+ case 3:
+ return read_pll_2(dev, 0x004000);
+ case 2:
+ return read_pll_1(dev, 0x004008);
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int
+nv40_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, 0x00c040);
+
+ perflvl->core = read_clk(dev, (ctrl & 0x00000003) >> 0);
+ perflvl->shader = read_clk(dev, (ctrl & 0x00000030) >> 4);
+ perflvl->memory = read_pll_2(dev, 0x4020);
+ return 0;
+}
+
+struct nv40_pm_state {
+ u32 ctrl;
+ u32 npll_ctrl;
+ u32 npll_coef;
+ u32 spll;
+ u32 mpll_ctrl;
+ u32 mpll_coef;
+};
+
+static int
+nv40_calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll,
+ u32 clk, int *N1, int *M1, int *N2, int *M2, int *log2P)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_clock *pclk = nouveau_clock(device);
+ struct nouveau_pll_vals coef;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, reg, pll);
+ if (ret)
+ return ret;
+
+ if (clk < pll->vco1.max_freq)
+ pll->vco2.max_freq = 0;
+
+ ret = pclk->pll_calc(pclk, pll, clk, &coef);
+ if (ret == 0)
+ return -ERANGE;
+
+ *N1 = coef.N1;
+ *M1 = coef.M1;
+ if (N2 && M2) {
+ if (pll->vco2.max_freq) {
+ *N2 = coef.N2;
+ *M2 = coef.M2;
+ } else {
+ *N2 = 1;
+ *M2 = 1;
+ }
+ }
+ *log2P = coef.log2P;
+ return 0;
+}
+
+void *
+nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nv40_pm_state *info;
+ struct nvbios_pll pll;
+ int N1, N2, M1, M2, log2P;
+ int ret;
+
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ /* core/geometric clock */
+ ret = nv40_calc_pll(dev, 0x004000, &pll, perflvl->core,
+ &N1, &M1, &N2, &M2, &log2P);
+ if (ret < 0)
+ goto out;
+
+ if (N2 == M2) {
+ info->npll_ctrl = 0x80000100 | (log2P << 16);
+ info->npll_coef = (N1 << 8) | M1;
+ } else {
+ info->npll_ctrl = 0xc0000000 | (log2P << 16);
+ info->npll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1;
+ }
+
+ /* use the second PLL for shader/rop clock, if it differs from core */
+ if (perflvl->shader && perflvl->shader != perflvl->core) {
+ ret = nv40_calc_pll(dev, 0x004008, &pll, perflvl->shader,
+ &N1, &M1, NULL, NULL, &log2P);
+ if (ret < 0)
+ goto out;
+
+ info->spll = 0xc0000000 | (log2P << 16) | (N1 << 8) | M1;
+ info->ctrl = 0x00000223;
+ } else {
+ info->spll = 0x00000000;
+ info->ctrl = 0x00000333;
+ }
+
+ /* memory clock */
+ if (!perflvl->memory) {
+ info->mpll_ctrl = 0x00000000;
+ goto out;
+ }
+
+ ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory,
+ &N1, &M1, &N2, &M2, &log2P);
+ if (ret < 0)
+ goto out;
+
+ info->mpll_ctrl = 0x80000000 | (log2P << 16);
+ info->mpll_ctrl |= min2(pll.bias_p + log2P, pll.max_p) << 20;
+ if (N2 == M2) {
+ info->mpll_ctrl |= 0x00000100;
+ info->mpll_coef = (N1 << 8) | M1;
+ } else {
+ info->mpll_ctrl |= 0x40000000;
+ info->mpll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1;
+ }
+
+out:
+ if (ret < 0) {
+ kfree(info);
+ info = ERR_PTR(ret);
+ }
+ return info;
+}
+
+static bool
+nv40_pm_gr_idle(void *data)
+{
+ struct drm_device *dev = data;
+ struct nouveau_device *device = nouveau_dev(dev);
+
+ if ((nv_rd32(device, 0x400760) & 0x000000f0) >> 4 !=
+ (nv_rd32(device, 0x400760) & 0x0000000f))
+ return false;
+
+ if (nv_rd32(device, 0x400700))
+ return false;
+
+ return true;
+}
+
+int
+nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fifo *pfifo = nouveau_fifo(device);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nv40_pm_state *info = pre_state;
+ unsigned long flags;
+ struct bit_entry M;
+ u32 crtc_mask = 0;
+ u8 sr1[2];
+ int i, ret = -EAGAIN;
+
+ /* determine which CRTCs are active, fetch VGA_SR1 for each */
+ for (i = 0; i < 2; i++) {
+ u32 vbl = nv_rd32(device, 0x600808 + (i * 0x2000));
+ u32 cnt = 0;
+ do {
+ if (vbl != nv_rd32(device, 0x600808 + (i * 0x2000))) {
+ nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+ sr1[i] = nv_rd08(device, 0x0c03c5 + (i * 0x2000));
+ if (!(sr1[i] & 0x20))
+ crtc_mask |= (1 << i);
+ break;
+ }
+ udelay(1);
+ } while (cnt++ < 32);
+ }
+
+ /* halt and idle engines */
+ pfifo->pause(pfifo, &flags);
+
+ if (!nv_wait_cb(device, nv40_pm_gr_idle, dev))
+ goto resume;
+
+ ret = 0;
+
+ /* set engine clocks */
+ nv_mask(device, 0x00c040, 0x00000333, 0x00000000);
+ nv_wr32(device, 0x004004, info->npll_coef);
+ nv_mask(device, 0x004000, 0xc0070100, info->npll_ctrl);
+ nv_mask(device, 0x004008, 0xc007ffff, info->spll);
+ mdelay(5);
+ nv_mask(device, 0x00c040, 0x00000333, info->ctrl);
+
+ if (!info->mpll_ctrl)
+ goto resume;
+
+ /* wait for vblank start on active crtcs, disable memory access */
+ for (i = 0; i < 2; i++) {
+ if (!(crtc_mask & (1 << i)))
+ continue;
+ nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000);
+ nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
+ nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+ nv_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
+ }
+
+ /* prepare ram for reclocking */
+ nv_wr32(device, 0x1002d4, 0x00000001); /* precharge */
+ nv_wr32(device, 0x1002d0, 0x00000001); /* refresh */
+ nv_wr32(device, 0x1002d0, 0x00000001); /* refresh */
+ nv_mask(device, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
+ nv_wr32(device, 0x1002dc, 0x00000001); /* enable self-refresh */
+
+ /* change the PLL of each memory partition */
+ nv_mask(device, 0x00c040, 0x0000c000, 0x00000000);
+ switch (nv_device(drm->device)->chipset) {
+ case 0x40:
+ case 0x45:
+ case 0x41:
+ case 0x42:
+ case 0x47:
+ nv_mask(device, 0x004044, 0xc0771100, info->mpll_ctrl);
+ nv_mask(device, 0x00402c, 0xc0771100, info->mpll_ctrl);
+ nv_wr32(device, 0x004048, info->mpll_coef);
+ nv_wr32(device, 0x004030, info->mpll_coef);
+ case 0x43:
+ case 0x49:
+ case 0x4b:
+ nv_mask(device, 0x004038, 0xc0771100, info->mpll_ctrl);
+ nv_wr32(device, 0x00403c, info->mpll_coef);
+ default:
+ nv_mask(device, 0x004020, 0xc0771100, info->mpll_ctrl);
+ nv_wr32(device, 0x004024, info->mpll_coef);
+ break;
+ }
+ udelay(100);
+ nv_mask(device, 0x00c040, 0x0000c000, 0x0000c000);
+
+ /* re-enable normal operation of memory controller */
+ nv_wr32(device, 0x1002dc, 0x00000000);
+ nv_mask(device, 0x100210, 0x80000000, 0x80000000);
+ udelay(100);
+
+ /* execute memory reset script from vbios */
+ if (!bit_table(dev, 'M', &M))
+ nouveau_bios_run_init_table(dev, ROM16(M.data[0]), NULL, 0);
+
+ /* make sure we're in vblank (hopefully the same one as before), and
+ * then re-enable crtc memory access
+ */
+ for (i = 0; i < 2; i++) {
+ if (!(crtc_mask & (1 << i)))
+ continue;
+ nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
+ nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+ nv_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i]);
+ }
+
+ /* resume engines */
+resume:
+ pfifo->start(pfifo, &flags);
+ kfree(info);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 4e384a2..f8e66c0 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1265,7 +1265,7 @@ nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
uint32_t start, uint32_t size)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- u32 end = min_t(u32, start + size, 256);
+ u32 end = max(start + size, (u32)256);
u32 i;
for (i = start; i < end; i++) {
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
new file mode 100644
index 0000000..4efc33f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -0,0 +1,855 @@
+/*
+ * Copyright 2010 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 <drm/drmP.h>
+#include "nouveau_drm.h"
+#include "nouveau_bios.h"
+#include "dispnv04/hw.h"
+#include "nouveau_pm.h"
+#include "nouveau_hwsq.h"
+
+#include "nv50_display.h"
+
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+enum clk_src {
+ clk_src_crystal,
+ clk_src_href,
+ clk_src_hclk,
+ clk_src_hclkm3,
+ clk_src_hclkm3d2,
+ clk_src_host,
+ clk_src_nvclk,
+ clk_src_sclk,
+ clk_src_mclk,
+ clk_src_vdec,
+ clk_src_dom6
+};
+
+static u32 read_clk(struct drm_device *, enum clk_src);
+
+static u32
+read_div(struct drm_device *dev)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ switch (nv_device(drm->device)->chipset) {
+ case 0x50: /* it exists, but only has bit 31, not the dividers.. */
+ case 0x84:
+ case 0x86:
+ case 0x98:
+ case 0xa0:
+ return nv_rd32(device, 0x004700);
+ case 0x92:
+ case 0x94:
+ case 0x96:
+ return nv_rd32(device, 0x004800);
+ default:
+ return 0x00000000;
+ }
+}
+
+static u32
+read_pll_src(struct drm_device *dev, u32 base)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 coef, ref = read_clk(dev, clk_src_crystal);
+ u32 rsel = nv_rd32(device, 0x00e18c);
+ int P, N, M, id;
+
+ switch (nv_device(drm->device)->chipset) {
+ case 0x50:
+ case 0xa0:
+ switch (base) {
+ case 0x4020:
+ case 0x4028: id = !!(rsel & 0x00000004); break;
+ case 0x4008: id = !!(rsel & 0x00000008); break;
+ case 0x4030: id = 0; break;
+ default:
+ NV_ERROR(drm, "ref: bad pll 0x%06x\n", base);
+ return 0;
+ }
+
+ coef = nv_rd32(device, 0x00e81c + (id * 0x0c));
+ ref *= (coef & 0x01000000) ? 2 : 4;
+ P = (coef & 0x00070000) >> 16;
+ N = ((coef & 0x0000ff00) >> 8) + 1;
+ M = ((coef & 0x000000ff) >> 0) + 1;
+ break;
+ case 0x84:
+ case 0x86:
+ case 0x92:
+ coef = nv_rd32(device, 0x00e81c);
+ P = (coef & 0x00070000) >> 16;
+ N = (coef & 0x0000ff00) >> 8;
+ M = (coef & 0x000000ff) >> 0;
+ break;
+ case 0x94:
+ case 0x96:
+ case 0x98:
+ rsel = nv_rd32(device, 0x00c050);
+ switch (base) {
+ case 0x4020: rsel = (rsel & 0x00000003) >> 0; break;
+ case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break;
+ case 0x4028: rsel = (rsel & 0x00001800) >> 11; break;
+ case 0x4030: rsel = 3; break;
+ default:
+ NV_ERROR(drm, "ref: bad pll 0x%06x\n", base);
+ return 0;
+ }
+
+ switch (rsel) {
+ case 0: id = 1; break;
+ case 1: return read_clk(dev, clk_src_crystal);
+ case 2: return read_clk(dev, clk_src_href);
+ case 3: id = 0; break;
+ }
+
+ coef = nv_rd32(device, 0x00e81c + (id * 0x28));
+ P = (nv_rd32(device, 0x00e824 + (id * 0x28)) >> 16) & 7;
+ P += (coef & 0x00070000) >> 16;
+ N = (coef & 0x0000ff00) >> 8;
+ M = (coef & 0x000000ff) >> 0;
+ break;
+ default:
+ BUG_ON(1);
+ }
+
+ if (M)
+ return (ref * N / M) >> P;
+ return 0;
+}
+
+static u32
+read_pll_ref(struct drm_device *dev, u32 base)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 src, mast = nv_rd32(device, 0x00c040);
+
+ switch (base) {
+ case 0x004028:
+ src = !!(mast & 0x00200000);
+ break;
+ case 0x004020:
+ src = !!(mast & 0x00400000);
+ break;
+ case 0x004008:
+ src = !!(mast & 0x00010000);
+ break;
+ case 0x004030:
+ src = !!(mast & 0x02000000);
+ break;
+ case 0x00e810:
+ return read_clk(dev, clk_src_crystal);
+ default:
+ NV_ERROR(drm, "bad pll 0x%06x\n", base);
+ return 0;
+ }
+
+ if (src)
+ return read_clk(dev, clk_src_href);
+ return read_pll_src(dev, base);
+}
+
+static u32
+read_pll(struct drm_device *dev, u32 base)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 mast = nv_rd32(device, 0x00c040);
+ u32 ctrl = nv_rd32(device, base + 0);
+ u32 coef = nv_rd32(device, base + 4);
+ u32 ref = read_pll_ref(dev, base);
+ u32 clk = 0;
+ int N1, N2, M1, M2;
+
+ if (base == 0x004028 && (mast & 0x00100000)) {
+ /* wtf, appears to only disable post-divider on nva0 */
+ if (nv_device(drm->device)->chipset != 0xa0)
+ return read_clk(dev, clk_src_dom6);
+ }
+
+ N2 = (coef & 0xff000000) >> 24;
+ M2 = (coef & 0x00ff0000) >> 16;
+ N1 = (coef & 0x0000ff00) >> 8;
+ M1 = (coef & 0x000000ff);
+ if ((ctrl & 0x80000000) && M1) {
+ clk = ref * N1 / M1;
+ if ((ctrl & 0x40000100) == 0x40000000) {
+ if (M2)
+ clk = clk * N2 / M2;
+ else
+ clk = 0;
+ }
+ }
+
+ return clk;
+}
+
+static u32
+read_clk(struct drm_device *dev, enum clk_src src)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 mast = nv_rd32(device, 0x00c040);
+ u32 P = 0;
+
+ switch (src) {
+ case clk_src_crystal:
+ return device->crystal;
+ case clk_src_href:
+ return 100000; /* PCIE reference clock */
+ case clk_src_hclk:
+ return read_clk(dev, clk_src_href) * 27778 / 10000;
+ case clk_src_hclkm3:
+ return read_clk(dev, clk_src_hclk) * 3;
+ case clk_src_hclkm3d2:
+ return read_clk(dev, clk_src_hclk) * 3 / 2;
+ case clk_src_host:
+ switch (mast & 0x30000000) {
+ case 0x00000000: return read_clk(dev, clk_src_href);
+ case 0x10000000: break;
+ case 0x20000000: /* !0x50 */
+ case 0x30000000: return read_clk(dev, clk_src_hclk);
+ }
+ break;
+ case clk_src_nvclk:
+ if (!(mast & 0x00100000))
+ P = (nv_rd32(device, 0x004028) & 0x00070000) >> 16;
+ switch (mast & 0x00000003) {
+ case 0x00000000: return read_clk(dev, clk_src_crystal) >> P;
+ case 0x00000001: return read_clk(dev, clk_src_dom6);
+ case 0x00000002: return read_pll(dev, 0x004020) >> P;
+ case 0x00000003: return read_pll(dev, 0x004028) >> P;
+ }
+ break;
+ case clk_src_sclk:
+ P = (nv_rd32(device, 0x004020) & 0x00070000) >> 16;
+ switch (mast & 0x00000030) {
+ case 0x00000000:
+ if (mast & 0x00000080)
+ return read_clk(dev, clk_src_host) >> P;
+ return read_clk(dev, clk_src_crystal) >> P;
+ case 0x00000010: break;
+ case 0x00000020: return read_pll(dev, 0x004028) >> P;
+ case 0x00000030: return read_pll(dev, 0x004020) >> P;
+ }
+ break;
+ case clk_src_mclk:
+ P = (nv_rd32(device, 0x004008) & 0x00070000) >> 16;
+ if (nv_rd32(device, 0x004008) & 0x00000200) {
+ switch (mast & 0x0000c000) {
+ case 0x00000000:
+ return read_clk(dev, clk_src_crystal) >> P;
+ case 0x00008000:
+ case 0x0000c000:
+ return read_clk(dev, clk_src_href) >> P;
+ }
+ } else {
+ return read_pll(dev, 0x004008) >> P;
+ }
+ break;
+ case clk_src_vdec:
+ P = (read_div(dev) & 0x00000700) >> 8;
+ switch (nv_device(drm->device)->chipset) {
+ case 0x84:
+ case 0x86:
+ case 0x92:
+ case 0x94:
+ case 0x96:
+ case 0xa0:
+ switch (mast & 0x00000c00) {
+ case 0x00000000:
+ if (nv_device(drm->device)->chipset == 0xa0) /* wtf?? */
+ return read_clk(dev, clk_src_nvclk) >> P;
+ return read_clk(dev, clk_src_crystal) >> P;
+ case 0x00000400:
+ return 0;
+ case 0x00000800:
+ if (mast & 0x01000000)
+ return read_pll(dev, 0x004028) >> P;
+ return read_pll(dev, 0x004030) >> P;
+ case 0x00000c00:
+ return read_clk(dev, clk_src_nvclk) >> P;
+ }
+ break;
+ case 0x98:
+ switch (mast & 0x00000c00) {
+ case 0x00000000:
+ return read_clk(dev, clk_src_nvclk) >> P;
+ case 0x00000400:
+ return 0;
+ case 0x00000800:
+ return read_clk(dev, clk_src_hclkm3d2) >> P;
+ case 0x00000c00:
+ return read_clk(dev, clk_src_mclk) >> P;
+ }
+ break;
+ }
+ break;
+ case clk_src_dom6:
+ switch (nv_device(drm->device)->chipset) {
+ case 0x50:
+ case 0xa0:
+ return read_pll(dev, 0x00e810) >> 2;
+ case 0x84:
+ case 0x86:
+ case 0x92:
+ case 0x94:
+ case 0x96:
+ case 0x98:
+ P = (read_div(dev) & 0x00000007) >> 0;
+ switch (mast & 0x0c000000) {
+ case 0x00000000: return read_clk(dev, clk_src_href);
+ case 0x04000000: break;
+ case 0x08000000: return read_clk(dev, clk_src_hclk);
+ case 0x0c000000:
+ return read_clk(dev, clk_src_hclkm3) >> P;
+ }
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+
+ NV_DEBUG(drm, "unknown clock source %d 0x%08x\n", src, mast);
+ return 0;
+}
+
+int
+nv50_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ if (nv_device(drm->device)->chipset == 0xaa ||
+ nv_device(drm->device)->chipset == 0xac)
+ return 0;
+
+ perflvl->core = read_clk(dev, clk_src_nvclk);
+ perflvl->shader = read_clk(dev, clk_src_sclk);
+ perflvl->memory = read_clk(dev, clk_src_mclk);
+ if (nv_device(drm->device)->chipset != 0x50) {
+ perflvl->vdec = read_clk(dev, clk_src_vdec);
+ perflvl->dom6 = read_clk(dev, clk_src_dom6);
+ }
+
+ return 0;
+}
+
+struct nv50_pm_state {
+ struct nouveau_pm_level *perflvl;
+ struct hwsq_ucode eclk_hwsq;
+ struct hwsq_ucode mclk_hwsq;
+ u32 mscript;
+ u32 mmast;
+ u32 mctrl;
+ u32 mcoef;
+};
+
+static u32
+calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll,
+ u32 clk, int *N1, int *M1, int *log2P)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_clock *pclk = nouveau_clock(device);
+ struct nouveau_pll_vals coef;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, reg, pll);
+ if (ret)
+ return 0;
+
+ pll->vco2.max_freq = 0;
+ pll->refclk = read_pll_ref(dev, reg);
+ if (!pll->refclk)
+ return 0;
+
+ ret = pclk->pll_calc(pclk, pll, clk, &coef);
+ if (ret == 0)
+ return 0;
+
+ *N1 = coef.N1;
+ *M1 = coef.M1;
+ *log2P = coef.log2P;
+ return ret;
+}
+
+static inline u32
+calc_div(u32 src, u32 target, int *div)
+{
+ u32 clk0 = src, clk1 = src;
+ for (*div = 0; *div <= 7; (*div)++) {
+ if (clk0 <= target) {
+ clk1 = clk0 << (*div ? 1 : 0);
+ break;
+ }
+ clk0 >>= 1;
+ }
+
+ if (target - clk0 <= clk1 - target)
+ return clk0;
+ (*div)--;
+ return clk1;
+}
+
+static inline u32
+clk_same(u32 a, u32 b)
+{
+ return ((a / 1000) == (b / 1000));
+}
+
+static void
+mclk_precharge(struct nouveau_mem_exec_func *exec)
+{
+ struct nv50_pm_state *info = exec->priv;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+
+ hwsq_wr32(hwsq, 0x1002d4, 0x00000001);
+}
+
+static void
+mclk_refresh(struct nouveau_mem_exec_func *exec)
+{
+ struct nv50_pm_state *info = exec->priv;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+
+ hwsq_wr32(hwsq, 0x1002d0, 0x00000001);
+}
+
+static void
+mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable)
+{
+ struct nv50_pm_state *info = exec->priv;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+
+ hwsq_wr32(hwsq, 0x100210, enable ? 0x80000000 : 0x00000000);
+}
+
+static void
+mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable)
+{
+ struct nv50_pm_state *info = exec->priv;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+
+ hwsq_wr32(hwsq, 0x1002dc, enable ? 0x00000001 : 0x00000000);
+}
+
+static void
+mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec)
+{
+ struct nv50_pm_state *info = exec->priv;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+
+ if (nsec > 1000)
+ hwsq_usec(hwsq, (nsec + 500) / 1000);
+}
+
+static u32
+mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ if (mr <= 1)
+ return nv_rd32(device, 0x1002c0 + ((mr - 0) * 4));
+ if (mr <= 3)
+ return nv_rd32(device, 0x1002e0 + ((mr - 2) * 4));
+ return 0;
+}
+
+static void
+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);
+ struct nv50_pm_state *info = exec->priv;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+
+ if (mr <= 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)
+ hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data);
+ hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data);
+ }
+}
+
+static void
+mclk_clock_set(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nv50_pm_state *info = exec->priv;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+ u32 ctrl = nv_rd32(device, 0x004008);
+
+ info->mmast = nv_rd32(device, 0x00c040);
+ info->mmast &= ~0xc0000000; /* get MCLK_2 from HREF */
+ info->mmast |= 0x0000c000; /* use MCLK_2 as MPLL_BYPASS clock */
+
+ hwsq_wr32(hwsq, 0xc040, info->mmast);
+ hwsq_wr32(hwsq, 0x4008, ctrl | 0x00000200); /* bypass MPLL */
+ if (info->mctrl & 0x80000000)
+ hwsq_wr32(hwsq, 0x400c, info->mcoef);
+ hwsq_wr32(hwsq, 0x4008, info->mctrl);
+}
+
+static void
+mclk_timing_set(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nv50_pm_state *info = exec->priv;
+ struct nouveau_pm_level *perflvl = info->perflvl;
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+ int i;
+
+ for (i = 0; i < 9; i++) {
+ u32 reg = 0x100220 + (i * 4);
+ u32 val = nv_rd32(device, reg);
+ if (val != perflvl->timing.reg[i])
+ hwsq_wr32(hwsq, reg, perflvl->timing.reg[i]);
+ }
+}
+
+static int
+calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
+ struct nv50_pm_state *info)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 crtc_mask = 0; /*XXX: nv50_display_active_crtcs(dev); */
+ struct nouveau_mem_exec_func exec = {
+ .dev = dev,
+ .precharge = mclk_precharge,
+ .refresh = mclk_refresh,
+ .refresh_auto = mclk_refresh_auto,
+ .refresh_self = mclk_refresh_self,
+ .wait = mclk_wait,
+ .mrg = mclk_mrg,
+ .mrs = mclk_mrs,
+ .clock_set = mclk_clock_set,
+ .timing_set = mclk_timing_set,
+ .priv = info
+ };
+ struct hwsq_ucode *hwsq = &info->mclk_hwsq;
+ struct nvbios_pll pll;
+ int N, M, P;
+ int ret;
+
+ /* use pcie refclock if possible, otherwise use mpll */
+ info->mctrl = nv_rd32(device, 0x004008);
+ info->mctrl &= ~0x81ff0200;
+ if (clk_same(perflvl->memory, read_clk(dev, clk_src_href))) {
+ info->mctrl |= 0x00000200 | (pll.bias_p << 19);
+ } else {
+ ret = calc_pll(dev, 0x4008, &pll, perflvl->memory, &N, &M, &P);
+ if (ret == 0)
+ return -EINVAL;
+
+ info->mctrl |= 0x80000000 | (P << 22) | (P << 16);
+ info->mctrl |= pll.bias_p << 19;
+ info->mcoef = (N << 8) | M;
+ }
+
+ /* build the ucode which will reclock the memory for us */
+ hwsq_init(hwsq);
+ if (crtc_mask) {
+ hwsq_op5f(hwsq, crtc_mask, 0x00); /* wait for scanout */
+ hwsq_op5f(hwsq, crtc_mask, 0x01); /* wait for vblank */
+ }
+ if (nv_device(drm->device)->chipset >= 0x92)
+ hwsq_wr32(hwsq, 0x611200, 0x00003300); /* disable scanout */
+ hwsq_setf(hwsq, 0x10, 0); /* disable bus access */
+ hwsq_op5f(hwsq, 0x00, 0x01); /* no idea :s */
+
+ ret = nouveau_mem_exec(&exec, perflvl);
+ if (ret)
+ return ret;
+
+ hwsq_setf(hwsq, 0x10, 1); /* enable bus access */
+ hwsq_op5f(hwsq, 0x00, 0x00); /* no idea, reverse of 0x00, 0x01? */
+ if (nv_device(drm->device)->chipset >= 0x92)
+ hwsq_wr32(hwsq, 0x611200, 0x00003330); /* enable scanout */
+ hwsq_fini(hwsq);
+ return 0;
+}
+
+void *
+nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nv50_pm_state *info;
+ struct hwsq_ucode *hwsq;
+ struct nvbios_pll pll;
+ u32 out, mast, divs, ctrl;
+ int clk, ret = -EINVAL;
+ int N, M, P1, P2;
+
+ if (nv_device(drm->device)->chipset == 0xaa ||
+ nv_device(drm->device)->chipset == 0xac)
+ return ERR_PTR(-ENODEV);
+
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+ info->perflvl = perflvl;
+
+ /* memory: build hwsq ucode which we'll use to reclock memory.
+ * use pcie refclock if possible, otherwise use mpll */
+ info->mclk_hwsq.len = 0;
+ if (perflvl->memory) {
+ ret = calc_mclk(dev, perflvl, info);
+ if (ret)
+ goto error;
+ info->mscript = perflvl->memscript;
+ }
+
+ divs = read_div(dev);
+ mast = info->mmast;
+
+ /* start building HWSQ script for engine reclocking */
+ hwsq = &info->eclk_hwsq;
+ hwsq_init(hwsq);
+ hwsq_setf(hwsq, 0x10, 0); /* disable bus access */
+ hwsq_op5f(hwsq, 0x00, 0x01); /* wait for access disabled? */
+
+ /* vdec/dom6: switch to "safe" clocks temporarily */
+ if (perflvl->vdec) {
+ mast &= ~0x00000c00;
+ divs &= ~0x00000700;
+ }
+
+ if (perflvl->dom6) {
+ mast &= ~0x0c000000;
+ divs &= ~0x00000007;
+ }
+
+ hwsq_wr32(hwsq, 0x00c040, mast);
+
+ /* vdec: avoid modifying xpll until we know exactly how the other
+ * clock domains work, i suspect at least some of them can also be
+ * tied to xpll...
+ */
+ if (perflvl->vdec) {
+ /* see how close we can get using nvclk as a source */
+ clk = calc_div(perflvl->core, perflvl->vdec, &P1);
+
+ /* see how close we can get using xpll/hclk as a source */
+ if (nv_device(drm->device)->chipset != 0x98)
+ out = read_pll(dev, 0x004030);
+ else
+ out = read_clk(dev, clk_src_hclkm3d2);
+ out = calc_div(out, perflvl->vdec, &P2);
+
+ /* select whichever gets us closest */
+ if (abs((int)perflvl->vdec - clk) <=
+ abs((int)perflvl->vdec - out)) {
+ if (nv_device(drm->device)->chipset != 0x98)
+ mast |= 0x00000c00;
+ divs |= P1 << 8;
+ } else {
+ mast |= 0x00000800;
+ divs |= P2 << 8;
+ }
+ }
+
+ /* dom6: nfi what this is, but we're limited to various combinations
+ * of the host clock frequency
+ */
+ if (perflvl->dom6) {
+ if (clk_same(perflvl->dom6, read_clk(dev, clk_src_href))) {
+ mast |= 0x00000000;
+ } else
+ if (clk_same(perflvl->dom6, read_clk(dev, clk_src_hclk))) {
+ mast |= 0x08000000;
+ } else {
+ clk = read_clk(dev, clk_src_hclk) * 3;
+ clk = calc_div(clk, perflvl->dom6, &P1);
+
+ mast |= 0x0c000000;
+ divs |= P1;
+ }
+ }
+
+ /* vdec/dom6: complete switch to new clocks */
+ switch (nv_device(drm->device)->chipset) {
+ case 0x92:
+ case 0x94:
+ case 0x96:
+ hwsq_wr32(hwsq, 0x004800, divs);
+ break;
+ default:
+ hwsq_wr32(hwsq, 0x004700, divs);
+ break;
+ }
+
+ hwsq_wr32(hwsq, 0x00c040, mast);
+
+ /* core/shader: make sure sclk/nvclk are disconnected from their
+ * PLLs (nvclk to dom6, sclk to hclk)
+ */
+ if (nv_device(drm->device)->chipset < 0x92)
+ mast = (mast & ~0x001000b0) | 0x00100080;
+ else
+ mast = (mast & ~0x000000b3) | 0x00000081;
+
+ hwsq_wr32(hwsq, 0x00c040, mast);
+
+ /* core: for the moment at least, always use nvpll */
+ clk = calc_pll(dev, 0x4028, &pll, perflvl->core, &N, &M, &P1);
+ if (clk == 0)
+ goto error;
+
+ ctrl = nv_rd32(device, 0x004028) & ~0xc03f0100;
+ mast &= ~0x00100000;
+ mast |= 3;
+
+ hwsq_wr32(hwsq, 0x004028, 0x80000000 | (P1 << 19) | (P1 << 16) | ctrl);
+ hwsq_wr32(hwsq, 0x00402c, (N << 8) | M);
+
+ /* shader: tie to nvclk if possible, otherwise use spll. have to be
+ * very careful that the shader clock is at least twice the core, or
+ * some chipsets will be very unhappy. i expect most or all of these
+ * cases will be handled by tying to nvclk, but it's possible there's
+ * corners
+ */
+ ctrl = nv_rd32(device, 0x004020) & ~0xc03f0100;
+
+ if (P1-- && perflvl->shader == (perflvl->core << 1)) {
+ hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl);
+ hwsq_wr32(hwsq, 0x00c040, 0x00000020 | mast);
+ } else {
+ clk = calc_pll(dev, 0x4020, &pll, perflvl->shader, &N, &M, &P1);
+ if (clk == 0)
+ goto error;
+ ctrl |= 0x80000000;
+
+ hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl);
+ hwsq_wr32(hwsq, 0x004024, (N << 8) | M);
+ hwsq_wr32(hwsq, 0x00c040, 0x00000030 | mast);
+ }
+
+ hwsq_setf(hwsq, 0x10, 1); /* enable bus access */
+ hwsq_op5f(hwsq, 0x00, 0x00); /* wait for access enabled? */
+ hwsq_fini(hwsq);
+
+ return info;
+error:
+ kfree(info);
+ return ERR_PTR(ret);
+}
+
+static int
+prog_hwsq(struct drm_device *dev, struct hwsq_ucode *hwsq)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 hwsq_data, hwsq_kick;
+ int i;
+
+ if (nv_device(drm->device)->chipset < 0x94) {
+ hwsq_data = 0x001400;
+ hwsq_kick = 0x00000003;
+ } else {
+ hwsq_data = 0x080000;
+ hwsq_kick = 0x00000001;
+ }
+ /* upload hwsq ucode */
+ nv_mask(device, 0x001098, 0x00000008, 0x00000000);
+ nv_wr32(device, 0x001304, 0x00000000);
+ if (nv_device(drm->device)->chipset >= 0x92)
+ nv_wr32(device, 0x001318, 0x00000000);
+ for (i = 0; i < hwsq->len / 4; i++)
+ nv_wr32(device, hwsq_data + (i * 4), hwsq->ptr.u32[i]);
+ nv_mask(device, 0x001098, 0x00000018, 0x00000018);
+
+ /* launch, and wait for completion */
+ nv_wr32(device, 0x00130c, hwsq_kick);
+ if (!nv_wait(device, 0x001308, 0x00000100, 0x00000000)) {
+ NV_ERROR(drm, "hwsq ucode exec timed out\n");
+ NV_ERROR(drm, "0x001308: 0x%08x\n", nv_rd32(device, 0x001308));
+ for (i = 0; i < hwsq->len / 4; i++) {
+ NV_ERROR(drm, "0x%06x: 0x%08x\n", 0x1400 + (i * 4),
+ nv_rd32(device, 0x001400 + (i * 4)));
+ }
+
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int
+nv50_pm_clocks_set(struct drm_device *dev, void *data)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nv50_pm_state *info = data;
+ struct bit_entry M;
+ int ret = -EBUSY;
+
+ /* halt and idle execution engines */
+ nv_mask(device, 0x002504, 0x00000001, 0x00000001);
+ if (!nv_wait(device, 0x002504, 0x00000010, 0x00000010))
+ goto resume;
+ if (!nv_wait(device, 0x00251c, 0x0000003f, 0x0000003f))
+ goto resume;
+
+ /* program memory clock, if necessary - must come before engine clock
+ * reprogramming due to how we construct the hwsq scripts in pre()
+ */
+#define nouveau_bios_init_exec(a,b) nouveau_bios_run_init_table((a), (b), NULL, 0)
+ if (info->mclk_hwsq.len) {
+ /* execute some scripts that do ??? from the vbios.. */
+ if (!bit_table(dev, 'M', &M) && M.version == 1) {
+ if (M.length >= 6)
+ nouveau_bios_init_exec(dev, ROM16(M.data[5]));
+ if (M.length >= 8)
+ nouveau_bios_init_exec(dev, ROM16(M.data[7]));
+ if (M.length >= 10)
+ nouveau_bios_init_exec(dev, ROM16(M.data[9]));
+ nouveau_bios_init_exec(dev, info->mscript);
+ }
+
+ ret = prog_hwsq(dev, &info->mclk_hwsq);
+ if (ret)
+ goto resume;
+ }
+
+ /* program engine clocks */
+ ret = prog_hwsq(dev, &info->eclk_hwsq);
+
+resume:
+ nv_mask(device, 0x002504, 0x00000001, 0x00000000);
+ kfree(info);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c
new file mode 100644
index 0000000..0d0ed59
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nva3_pm.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright 2010 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 <drm/drmP.h>
+#include "nouveau_drm.h"
+#include "nouveau_bios.h"
+#include "nouveau_pm.h"
+
+#include <subdev/bios/pll.h>
+#include <subdev/bios.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+static u32 read_clk(struct drm_device *, int, bool);
+static u32 read_pll(struct drm_device *, int, u32);
+
+static u32
+read_vco(struct drm_device *dev, int clk)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 sctl = nv_rd32(device, 0x4120 + (clk * 4));
+ if ((sctl & 0x00000030) != 0x00000030)
+ return read_pll(dev, 0x41, 0x00e820);
+ return read_pll(dev, 0x42, 0x00e8a0);
+}
+
+static u32
+read_clk(struct drm_device *dev, int clk, bool ignore_en)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 sctl, sdiv, sclk;
+
+ /* refclk for the 0xe8xx plls is a fixed frequency */
+ if (clk >= 0x40) {
+ if (nv_device(drm->device)->chipset == 0xaf) {
+ /* no joke.. seriously.. sigh.. */
+ return nv_rd32(device, 0x00471c) * 1000;
+ }
+
+ return device->crystal;
+ }
+
+ sctl = nv_rd32(device, 0x4120 + (clk * 4));
+ if (!ignore_en && !(sctl & 0x00000100))
+ return 0;
+
+ switch (sctl & 0x00003000) {
+ case 0x00000000:
+ return device->crystal;
+ case 0x00002000:
+ if (sctl & 0x00000040)
+ return 108000;
+ return 100000;
+ case 0x00003000:
+ sclk = read_vco(dev, clk);
+ sdiv = ((sctl & 0x003f0000) >> 16) + 2;
+ return (sclk * 2) / sdiv;
+ default:
+ return 0;
+ }
+}
+
+static u32
+read_pll(struct drm_device *dev, int clk, u32 pll)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, pll + 0);
+ u32 sclk = 0, P = 1, N = 1, M = 1;
+
+ if (!(ctrl & 0x00000008)) {
+ if (ctrl & 0x00000001) {
+ u32 coef = nv_rd32(device, pll + 4);
+ M = (coef & 0x000000ff) >> 0;
+ N = (coef & 0x0000ff00) >> 8;
+ P = (coef & 0x003f0000) >> 16;
+
+ /* no post-divider on these.. */
+ if ((pll & 0x00ff00) == 0x00e800)
+ P = 1;
+
+ sclk = read_clk(dev, 0x00 + clk, false);
+ }
+ } else {
+ sclk = read_clk(dev, 0x10 + clk, false);
+ }
+
+ if (M * P)
+ return sclk * N / (M * P);
+ return 0;
+}
+
+struct creg {
+ u32 clk;
+ u32 pll;
+};
+
+static int
+calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_pll limits;
+ u32 oclk, sclk, sdiv;
+ int P, N, M, diff;
+ int ret;
+
+ reg->pll = 0;
+ reg->clk = 0;
+ if (!khz) {
+ NV_DEBUG(drm, "no clock for 0x%04x/0x%02x\n", pll, clk);
+ return 0;
+ }
+
+ switch (khz) {
+ case 27000:
+ reg->clk = 0x00000100;
+ return khz;
+ case 100000:
+ reg->clk = 0x00002100;
+ return khz;
+ case 108000:
+ reg->clk = 0x00002140;
+ return khz;
+ default:
+ sclk = read_vco(dev, clk);
+ sdiv = min((sclk * 2) / (khz - 2999), (u32)65);
+ /* if the clock has a PLL attached, and we can get a within
+ * [-2, 3) MHz of a divider, we'll disable the PLL and use
+ * the divider instead.
+ *
+ * divider can go as low as 2, limited here because NVIDIA
+ * and the VBIOS on my NVA8 seem to prefer using the PLL
+ * for 810MHz - is there a good reason?
+ */
+ if (sdiv > 4) {
+ oclk = (sclk * 2) / sdiv;
+ diff = khz - oclk;
+ if (!pll || (diff >= -2000 && diff < 3000)) {
+ reg->clk = (((sdiv - 2) << 16) | 0x00003100);
+ return oclk;
+ }
+ }
+
+ if (!pll) {
+ NV_ERROR(drm, "bad freq %02x: %d %d\n", clk, khz, sclk);
+ return -ERANGE;
+ }
+
+ break;
+ }
+
+ ret = nvbios_pll_parse(bios, pll, &limits);
+ if (ret)
+ return ret;
+
+ limits.refclk = read_clk(dev, clk - 0x10, true);
+ if (!limits.refclk)
+ return -EINVAL;
+
+ ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P);
+ if (ret >= 0) {
+ reg->clk = nv_rd32(device, 0x4120 + (clk * 4));
+ reg->pll = (P << 16) | (N << 8) | M;
+ }
+
+ return ret;
+}
+
+static void
+prog_pll(struct drm_device *dev, int clk, u32 pll, struct creg *reg)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ const u32 src0 = 0x004120 + (clk * 4);
+ const u32 src1 = 0x004160 + (clk * 4);
+ const u32 ctrl = pll + 0;
+ const u32 coef = pll + 4;
+
+ if (!reg->clk && !reg->pll) {
+ NV_DEBUG(drm, "no clock for %02x\n", clk);
+ return;
+ }
+
+ if (reg->pll) {
+ nv_mask(device, src0, 0x00000101, 0x00000101);
+ nv_wr32(device, coef, reg->pll);
+ nv_mask(device, ctrl, 0x00000015, 0x00000015);
+ nv_mask(device, ctrl, 0x00000010, 0x00000000);
+ nv_wait(device, ctrl, 0x00020000, 0x00020000);
+ nv_mask(device, ctrl, 0x00000010, 0x00000010);
+ nv_mask(device, ctrl, 0x00000008, 0x00000000);
+ nv_mask(device, src1, 0x00000100, 0x00000000);
+ nv_mask(device, src1, 0x00000001, 0x00000000);
+ } else {
+ nv_mask(device, src1, 0x003f3141, 0x00000101 | reg->clk);
+ nv_mask(device, ctrl, 0x00000018, 0x00000018);
+ udelay(20);
+ nv_mask(device, ctrl, 0x00000001, 0x00000000);
+ nv_mask(device, src0, 0x00000100, 0x00000000);
+ nv_mask(device, src0, 0x00000001, 0x00000000);
+ }
+}
+
+static void
+prog_clk(struct drm_device *dev, int clk, struct creg *reg)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ if (!reg->clk) {
+ NV_DEBUG(drm, "no clock for %02x\n", clk);
+ return;
+ }
+
+ nv_mask(device, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | reg->clk);
+}
+
+int
+nva3_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ perflvl->core = read_pll(dev, 0x00, 0x4200);
+ perflvl->shader = read_pll(dev, 0x01, 0x4220);
+ perflvl->memory = read_pll(dev, 0x02, 0x4000);
+ perflvl->unka0 = read_clk(dev, 0x20, false);
+ perflvl->vdec = read_clk(dev, 0x21, false);
+ perflvl->daemon = read_clk(dev, 0x25, false);
+ perflvl->copy = perflvl->core;
+ return 0;
+}
+
+struct nva3_pm_state {
+ struct nouveau_pm_level *perflvl;
+
+ struct creg nclk;
+ struct creg sclk;
+ struct creg vdec;
+ struct creg unka0;
+
+ struct creg mclk;
+ u8 *rammap;
+ u8 rammap_ver;
+ u8 rammap_len;
+ u8 *ramcfg;
+ u8 ramcfg_len;
+ u32 r004018;
+ u32 r100760;
+};
+
+void *
+nva3_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nva3_pm_state *info;
+ u8 ramcfg_cnt;
+ int ret;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ ret = calc_clk(dev, 0x10, 0x4200, perflvl->core, &info->nclk);
+ if (ret < 0)
+ goto out;
+
+ ret = calc_clk(dev, 0x11, 0x4220, perflvl->shader, &info->sclk);
+ if (ret < 0)
+ goto out;
+
+ ret = calc_clk(dev, 0x12, 0x4000, perflvl->memory, &info->mclk);
+ if (ret < 0)
+ goto out;
+
+ ret = calc_clk(dev, 0x20, 0x0000, perflvl->unka0, &info->unka0);
+ if (ret < 0)
+ goto out;
+
+ ret = calc_clk(dev, 0x21, 0x0000, perflvl->vdec, &info->vdec);
+ if (ret < 0)
+ goto out;
+
+ info->rammap = nouveau_perf_rammap(dev, perflvl->memory,
+ &info->rammap_ver,
+ &info->rammap_len,
+ &ramcfg_cnt, &info->ramcfg_len);
+ if (info->rammap_ver != 0x10 || info->rammap_len < 5)
+ info->rammap = NULL;
+
+ info->ramcfg = nouveau_perf_ramcfg(dev, perflvl->memory,
+ &info->rammap_ver,
+ &info->ramcfg_len);
+ if (info->rammap_ver != 0x10)
+ info->ramcfg = NULL;
+
+ info->perflvl = perflvl;
+out:
+ if (ret < 0) {
+ kfree(info);
+ info = ERR_PTR(ret);
+ }
+ return info;
+}
+
+static bool
+nva3_pm_grcp_idle(void *data)
+{
+ struct drm_device *dev = data;
+ struct nouveau_device *device = nouveau_dev(dev);
+
+ if (!(nv_rd32(device, 0x400304) & 0x00000001))
+ return true;
+ if (nv_rd32(device, 0x400308) == 0x0050001c)
+ return true;
+ return false;
+}
+
+static void
+mclk_precharge(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x1002d4, 0x00000001);
+}
+
+static void
+mclk_refresh(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x1002d0, 0x00000001);
+}
+
+static void
+mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x100210, enable ? 0x80000000 : 0x00000000);
+}
+
+static void
+mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x1002dc, enable ? 0x00000001 : 0x00000000);
+}
+
+static void
+mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ volatile u32 post = nv_rd32(device, 0); (void)post;
+ udelay((nsec + 500) / 1000);
+}
+
+static u32
+mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ if (mr <= 1)
+ return nv_rd32(device, 0x1002c0 + ((mr - 0) * 4));
+ if (mr <= 3)
+ return nv_rd32(device, 0x1002e0 + ((mr - 2) * 4));
+ return 0;
+}
+
+static void
+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)
+ 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)
+ nv_wr32(device, 0x1002e8 + ((mr - 2) * 4), data);
+ nv_wr32(device, 0x1002e0 + ((mr - 2) * 4), data);
+ }
+}
+
+static void
+mclk_clock_set(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nva3_pm_state *info = exec->priv;
+ u32 ctrl;
+
+ ctrl = nv_rd32(device, 0x004000);
+ if (!(ctrl & 0x00000008) && info->mclk.pll) {
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000008));
+ nv_mask(device, 0x1110e0, 0x00088000, 0x00088000);
+ nv_wr32(device, 0x004018, 0x00001000);
+ nv_wr32(device, 0x004000, (ctrl &= ~0x00000001));
+ nv_wr32(device, 0x004004, info->mclk.pll);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000001));
+ udelay(64);
+ nv_wr32(device, 0x004018, 0x00005000 | info->r004018);
+ udelay(20);
+ } else
+ if (!info->mclk.pll) {
+ nv_mask(device, 0x004168, 0x003f3040, info->mclk.clk);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000008));
+ nv_mask(device, 0x1110e0, 0x00088000, 0x00088000);
+ nv_wr32(device, 0x004018, 0x0000d000 | info->r004018);
+ }
+
+ if (info->rammap) {
+ if (info->ramcfg && (info->rammap[4] & 0x08)) {
+ u32 unk5a0 = (ROM16(info->ramcfg[5]) << 8) |
+ info->ramcfg[5];
+ u32 unk5a4 = ROM16(info->ramcfg[7]);
+ u32 unk804 = (info->ramcfg[9] & 0xf0) << 16 |
+ (info->ramcfg[3] & 0x0f) << 16 |
+ (info->ramcfg[9] & 0x0f) |
+ 0x80000000;
+ nv_wr32(device, 0x1005a0, unk5a0);
+ nv_wr32(device, 0x1005a4, unk5a4);
+ nv_wr32(device, 0x10f804, unk804);
+ nv_mask(device, 0x10053c, 0x00001000, 0x00000000);
+ } else {
+ nv_mask(device, 0x10053c, 0x00001000, 0x00001000);
+ nv_mask(device, 0x10f804, 0x80000000, 0x00000000);
+ nv_mask(device, 0x100760, 0x22222222, info->r100760);
+ nv_mask(device, 0x1007a0, 0x22222222, info->r100760);
+ nv_mask(device, 0x1007e0, 0x22222222, info->r100760);
+ }
+ }
+
+ if (info->mclk.pll) {
+ nv_mask(device, 0x1110e0, 0x00088000, 0x00011000);
+ nv_wr32(device, 0x004000, (ctrl &= ~0x00000008));
+ }
+}
+
+static void
+mclk_timing_set(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nva3_pm_state *info = exec->priv;
+ struct nouveau_pm_level *perflvl = info->perflvl;
+ int i;
+
+ for (i = 0; i < 9; i++)
+ nv_wr32(device, 0x100220 + (i * 4), perflvl->timing.reg[i]);
+
+ if (info->ramcfg) {
+ u32 data = (info->ramcfg[2] & 0x08) ? 0x00000000 : 0x00001000;
+ nv_mask(device, 0x100200, 0x00001000, data);
+ }
+
+ if (info->ramcfg) {
+ u32 unk714 = nv_rd32(device, 0x100714) & ~0xf0000010;
+ u32 unk718 = nv_rd32(device, 0x100718) & ~0x00000100;
+ u32 unk71c = nv_rd32(device, 0x10071c) & ~0x00000100;
+ if ( (info->ramcfg[2] & 0x20))
+ unk714 |= 0xf0000000;
+ if (!(info->ramcfg[2] & 0x04))
+ unk714 |= 0x00000010;
+ nv_wr32(device, 0x100714, unk714);
+
+ if (info->ramcfg[2] & 0x01)
+ unk71c |= 0x00000100;
+ nv_wr32(device, 0x10071c, unk71c);
+
+ if (info->ramcfg[2] & 0x02)
+ unk718 |= 0x00000100;
+ nv_wr32(device, 0x100718, unk718);
+
+ if (info->ramcfg[2] & 0x10)
+ nv_wr32(device, 0x111100, 0x48000000); /*XXX*/
+ }
+}
+
+static void
+prog_mem(struct drm_device *dev, struct nva3_pm_state *info)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_mem_exec_func exec = {
+ .dev = dev,
+ .precharge = mclk_precharge,
+ .refresh = mclk_refresh,
+ .refresh_auto = mclk_refresh_auto,
+ .refresh_self = mclk_refresh_self,
+ .wait = mclk_wait,
+ .mrg = mclk_mrg,
+ .mrs = mclk_mrs,
+ .clock_set = mclk_clock_set,
+ .timing_set = mclk_timing_set,
+ .priv = info
+ };
+ u32 ctrl;
+
+ /* XXX: where the fuck does 750MHz come from? */
+ if (info->perflvl->memory <= 750000) {
+ info->r004018 = 0x10000000;
+ info->r100760 = 0x22222222;
+ }
+
+ ctrl = nv_rd32(device, 0x004000);
+ if (ctrl & 0x00000008) {
+ if (info->mclk.pll) {
+ nv_mask(device, 0x004128, 0x00000101, 0x00000101);
+ nv_wr32(device, 0x004004, info->mclk.pll);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000001));
+ nv_wr32(device, 0x004000, (ctrl &= 0xffffffef));
+ nv_wait(device, 0x004000, 0x00020000, 0x00020000);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000010));
+ nv_wr32(device, 0x004018, 0x00005000 | info->r004018);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000004));
+ }
+ } else {
+ u32 ssel = 0x00000101;
+ if (info->mclk.clk)
+ ssel |= info->mclk.clk;
+ else
+ ssel |= 0x00080000; /* 324MHz, shouldn't matter... */
+ nv_mask(device, 0x004168, 0x003f3141, ctrl);
+ }
+
+ if (info->ramcfg) {
+ if (info->ramcfg[2] & 0x10) {
+ nv_mask(device, 0x111104, 0x00000600, 0x00000000);
+ } else {
+ nv_mask(device, 0x111100, 0x40000000, 0x40000000);
+ nv_mask(device, 0x111104, 0x00000180, 0x00000000);
+ }
+ }
+ if (info->rammap && !(info->rammap[4] & 0x02))
+ nv_mask(device, 0x100200, 0x00000800, 0x00000000);
+ nv_wr32(device, 0x611200, 0x00003300);
+ if (!(info->ramcfg[2] & 0x10))
+ nv_wr32(device, 0x111100, 0x4c020000); /*XXX*/
+
+ nouveau_mem_exec(&exec, info->perflvl);
+
+ nv_wr32(device, 0x611200, 0x00003330);
+ if (info->rammap && (info->rammap[4] & 0x02))
+ nv_mask(device, 0x100200, 0x00000800, 0x00000800);
+ if (info->ramcfg) {
+ if (info->ramcfg[2] & 0x10) {
+ nv_mask(device, 0x111104, 0x00000180, 0x00000180);
+ nv_mask(device, 0x111100, 0x40000000, 0x00000000);
+ } else {
+ nv_mask(device, 0x111104, 0x00000600, 0x00000600);
+ }
+ }
+
+ if (info->mclk.pll) {
+ nv_mask(device, 0x004168, 0x00000001, 0x00000000);
+ nv_mask(device, 0x004168, 0x00000100, 0x00000000);
+ } else {
+ nv_mask(device, 0x004000, 0x00000001, 0x00000000);
+ nv_mask(device, 0x004128, 0x00000001, 0x00000000);
+ nv_mask(device, 0x004128, 0x00000100, 0x00000000);
+ }
+}
+
+int
+nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nva3_pm_state *info = pre_state;
+ int ret = -EAGAIN;
+
+ /* prevent any new grctx switches from starting */
+ nv_wr32(device, 0x400324, 0x00000000);
+ nv_wr32(device, 0x400328, 0x0050001c); /* wait flag 0x1c */
+ /* wait for any pending grctx switches to complete */
+ if (!nv_wait_cb(device, nva3_pm_grcp_idle, dev)) {
+ NV_ERROR(drm, "pm: ctxprog didn't go idle\n");
+ goto cleanup;
+ }
+ /* freeze PFIFO */
+ nv_mask(device, 0x002504, 0x00000001, 0x00000001);
+ if (!nv_wait(device, 0x002504, 0x00000010, 0x00000010)) {
+ NV_ERROR(drm, "pm: fifo didn't go idle\n");
+ goto cleanup;
+ }
+
+ prog_pll(dev, 0x00, 0x004200, &info->nclk);
+ prog_pll(dev, 0x01, 0x004220, &info->sclk);
+ prog_clk(dev, 0x20, &info->unka0);
+ prog_clk(dev, 0x21, &info->vdec);
+
+ if (info->mclk.clk || info->mclk.pll)
+ prog_mem(dev, info);
+
+ ret = 0;
+
+cleanup:
+ /* unfreeze PFIFO */
+ nv_mask(device, 0x002504, 0x00000001, 0x00000000);
+ /* restore ctxprog to normal */
+ nv_wr32(device, 0x400324, 0x00000000);
+ nv_wr32(device, 0x400328, 0x0070009c); /* set flag 0x1c */
+ /* unblock it if necessary */
+ if (nv_rd32(device, 0x400308) == 0x0050001c)
+ nv_mask(device, 0x400824, 0x10000000, 0x10000000);
+ kfree(info);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c
new file mode 100644
index 0000000..3b7041c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvc0_pm.c
@@ -0,0 +1,599 @@
+/*
+ * 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
+ */
+
+#include "nouveau_drm.h"
+#include "nouveau_bios.h"
+#include "nouveau_pm.h"
+
+#include <subdev/bios/pll.h>
+#include <subdev/bios.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+static u32 read_div(struct drm_device *, int, u32, u32);
+static u32 read_pll(struct drm_device *, u32);
+
+static u32
+read_vco(struct drm_device *dev, u32 dsrc)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ssrc = nv_rd32(device, dsrc);
+ if (!(ssrc & 0x00000100))
+ return read_pll(dev, 0x00e800);
+ return read_pll(dev, 0x00e820);
+}
+
+static u32
+read_pll(struct drm_device *dev, u32 pll)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, pll + 0);
+ u32 coef = nv_rd32(device, pll + 4);
+ u32 P = (coef & 0x003f0000) >> 16;
+ u32 N = (coef & 0x0000ff00) >> 8;
+ u32 M = (coef & 0x000000ff) >> 0;
+ u32 sclk, doff;
+
+ if (!(ctrl & 0x00000001))
+ return 0;
+
+ switch (pll & 0xfff000) {
+ case 0x00e000:
+ sclk = 27000;
+ P = 1;
+ break;
+ case 0x137000:
+ doff = (pll - 0x137000) / 0x20;
+ sclk = read_div(dev, doff, 0x137120, 0x137140);
+ break;
+ case 0x132000:
+ switch (pll) {
+ case 0x132000:
+ sclk = read_pll(dev, 0x132020);
+ break;
+ case 0x132020:
+ sclk = read_div(dev, 0, 0x137320, 0x137330);
+ break;
+ default:
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+
+ return sclk * N / M / P;
+}
+
+static u32
+read_div(struct drm_device *dev, int doff, u32 dsrc, u32 dctl)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ssrc = nv_rd32(device, dsrc + (doff * 4));
+ u32 sctl = nv_rd32(device, dctl + (doff * 4));
+
+ switch (ssrc & 0x00000003) {
+ case 0:
+ if ((ssrc & 0x00030000) != 0x00030000)
+ return 27000;
+ return 108000;
+ case 2:
+ return 100000;
+ case 3:
+ if (sctl & 0x80000000) {
+ u32 sclk = read_vco(dev, dsrc + (doff * 4));
+ u32 sdiv = (sctl & 0x0000003f) + 2;
+ return (sclk * 2) / sdiv;
+ }
+
+ return read_vco(dev, dsrc + (doff * 4));
+ default:
+ return 0;
+ }
+}
+
+static u32
+read_mem(struct drm_device *dev)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ssel = nv_rd32(device, 0x1373f0);
+ if (ssel & 0x00000001)
+ return read_div(dev, 0, 0x137300, 0x137310);
+ return read_pll(dev, 0x132000);
+}
+
+static u32
+read_clk(struct drm_device *dev, int clk)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 sctl = nv_rd32(device, 0x137250 + (clk * 4));
+ u32 ssel = nv_rd32(device, 0x137100);
+ u32 sclk, sdiv;
+
+ if (ssel & (1 << clk)) {
+ if (clk < 7)
+ sclk = read_pll(dev, 0x137000 + (clk * 0x20));
+ else
+ sclk = read_pll(dev, 0x1370e0);
+ sdiv = ((sctl & 0x00003f00) >> 8) + 2;
+ } else {
+ sclk = read_div(dev, clk, 0x137160, 0x1371d0);
+ sdiv = ((sctl & 0x0000003f) >> 0) + 2;
+ }
+
+ if (sctl & 0x80000000)
+ return (sclk * 2) / sdiv;
+ return sclk;
+}
+
+int
+nvc0_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ perflvl->shader = read_clk(dev, 0x00);
+ perflvl->core = perflvl->shader / 2;
+ perflvl->memory = read_mem(dev);
+ perflvl->rop = read_clk(dev, 0x01);
+ perflvl->hub07 = read_clk(dev, 0x02);
+ perflvl->hub06 = read_clk(dev, 0x07);
+ perflvl->hub01 = read_clk(dev, 0x08);
+ perflvl->copy = read_clk(dev, 0x09);
+ perflvl->daemon = read_clk(dev, 0x0c);
+ perflvl->vdec = read_clk(dev, 0x0e);
+ return 0;
+}
+
+struct nvc0_pm_clock {
+ u32 freq;
+ u32 ssel;
+ u32 mdiv;
+ u32 dsrc;
+ u32 ddiv;
+ u32 coef;
+};
+
+struct nvc0_pm_state {
+ struct nouveau_pm_level *perflvl;
+ struct nvc0_pm_clock eng[16];
+ struct nvc0_pm_clock mem;
+};
+
+static u32
+calc_div(struct drm_device *dev, int clk, u32 ref, u32 freq, u32 *ddiv)
+{
+ u32 div = min((ref * 2) / freq, (u32)65);
+ if (div < 2)
+ div = 2;
+
+ *ddiv = div - 2;
+ return (ref * 2) / div;
+}
+
+static u32
+calc_src(struct drm_device *dev, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
+{
+ u32 sclk;
+
+ /* use one of the fixed frequencies if possible */
+ *ddiv = 0x00000000;
+ switch (freq) {
+ case 27000:
+ case 108000:
+ *dsrc = 0x00000000;
+ if (freq == 108000)
+ *dsrc |= 0x00030000;
+ return freq;
+ case 100000:
+ *dsrc = 0x00000002;
+ return freq;
+ default:
+ *dsrc = 0x00000003;
+ break;
+ }
+
+ /* otherwise, calculate the closest divider */
+ sclk = read_vco(dev, clk);
+ if (clk < 7)
+ sclk = calc_div(dev, clk, sclk, freq, ddiv);
+ return sclk;
+}
+
+static u32
+calc_pll(struct drm_device *dev, int clk, u32 freq, u32 *coef)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_pll limits;
+ int N, M, P, ret;
+
+ ret = nvbios_pll_parse(bios, 0x137000 + (clk * 0x20), &limits);
+ if (ret)
+ return 0;
+
+ limits.refclk = read_div(dev, clk, 0x137120, 0x137140);
+ if (!limits.refclk)
+ return 0;
+
+ ret = nva3_calc_pll(dev, &limits, freq, &N, NULL, &M, &P);
+ if (ret <= 0)
+ return 0;
+
+ *coef = (P << 16) | (N << 8) | M;
+ return ret;
+}
+
+/* A (likely rather simplified and incomplete) view of the clock tree
+ *
+ * Key:
+ *
+ * S: source select
+ * D: divider
+ * P: pll
+ * F: switch
+ *
+ * Engine clocks:
+ *
+ * 137250(D) ---- 137100(F0) ---- 137160(S)/1371d0(D) ------------------- ref
+ * (F1) ---- 1370X0(P) ---- 137120(S)/137140(D) ---- ref
+ *
+ * Not all registers exist for all clocks. For example: clocks >= 8 don't
+ * have their own PLL (all tied to clock 7's PLL when in PLL mode), nor do
+ * they have the divider at 1371d0, though the source selection at 137160
+ * still exists. You must use the divider at 137250 for these instead.
+ *
+ * Memory clock:
+ *
+ * TBD, read_mem() above is likely very wrong...
+ *
+ */
+
+static int
+calc_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info, u32 freq)
+{
+ u32 src0, div0, div1D, div1P = 0;
+ u32 clk0, clk1 = 0;
+
+ /* invalid clock domain */
+ if (!freq)
+ return 0;
+
+ /* first possible path, using only dividers */
+ clk0 = calc_src(dev, clk, freq, &src0, &div0);
+ clk0 = calc_div(dev, clk, clk0, freq, &div1D);
+
+ /* see if we can get any closer using PLLs */
+ if (clk0 != freq && (0x00004387 & (1 << clk))) {
+ if (clk < 7)
+ clk1 = calc_pll(dev, clk, freq, &info->coef);
+ else
+ clk1 = read_pll(dev, 0x1370e0);
+ clk1 = calc_div(dev, clk, clk1, freq, &div1P);
+ }
+
+ /* select the method which gets closest to target freq */
+ if (abs((int)freq - clk0) <= abs((int)freq - clk1)) {
+ info->dsrc = src0;
+ if (div0) {
+ info->ddiv |= 0x80000000;
+ info->ddiv |= div0 << 8;
+ info->ddiv |= div0;
+ }
+ if (div1D) {
+ info->mdiv |= 0x80000000;
+ info->mdiv |= div1D;
+ }
+ info->ssel = 0;
+ info->freq = clk0;
+ } else {
+ if (div1P) {
+ info->mdiv |= 0x80000000;
+ info->mdiv |= div1P << 8;
+ }
+ info->ssel = (1 << clk);
+ info->freq = clk1;
+ }
+
+ return 0;
+}
+
+static int
+calc_mem(struct drm_device *dev, struct nvc0_pm_clock *info, u32 freq)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_pll pll;
+ int N, M, P, ret;
+ u32 ctrl;
+
+ /* mclk pll input freq comes from another pll, make sure it's on */
+ ctrl = nv_rd32(device, 0x132020);
+ if (!(ctrl & 0x00000001)) {
+ /* if not, program it to 567MHz. nfi where this value comes
+ * from - it looks like it's in the pll limits table for
+ * 132000 but the binary driver ignores all my attempts to
+ * change this value.
+ */
+ nv_wr32(device, 0x137320, 0x00000103);
+ nv_wr32(device, 0x137330, 0x81200606);
+ nv_wait(device, 0x132020, 0x00010000, 0x00010000);
+ nv_wr32(device, 0x132024, 0x0001150f);
+ nv_mask(device, 0x132020, 0x00000001, 0x00000001);
+ nv_wait(device, 0x137390, 0x00020000, 0x00020000);
+ nv_mask(device, 0x132020, 0x00000004, 0x00000004);
+ }
+
+ /* for the moment, until the clock tree is better understood, use
+ * pll mode for all clock frequencies
+ */
+ ret = nvbios_pll_parse(bios, 0x132000, &pll);
+ if (ret == 0) {
+ pll.refclk = read_pll(dev, 0x132020);
+ if (pll.refclk) {
+ ret = nva3_calc_pll(dev, &pll, freq, &N, NULL, &M, &P);
+ if (ret > 0) {
+ info->coef = (P << 16) | (N << 8) | M;
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+void *
+nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nvc0_pm_state *info;
+ int ret;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ /* NFI why this is still in the performance table, the ROPCs appear
+ * to get their clock from clock 2 ("hub07", actually hub05 on this
+ * chip, but, anyway...) as well. nvatiming confirms hub05 and ROP
+ * are always the same freq with the binary driver even when the
+ * performance table says they should differ.
+ */
+ if (device->chipset == 0xd9)
+ perflvl->rop = 0;
+
+ if ((ret = calc_clk(dev, 0x00, &info->eng[0x00], perflvl->shader)) ||
+ (ret = calc_clk(dev, 0x01, &info->eng[0x01], perflvl->rop)) ||
+ (ret = calc_clk(dev, 0x02, &info->eng[0x02], perflvl->hub07)) ||
+ (ret = calc_clk(dev, 0x07, &info->eng[0x07], perflvl->hub06)) ||
+ (ret = calc_clk(dev, 0x08, &info->eng[0x08], perflvl->hub01)) ||
+ (ret = calc_clk(dev, 0x09, &info->eng[0x09], perflvl->copy)) ||
+ (ret = calc_clk(dev, 0x0c, &info->eng[0x0c], perflvl->daemon)) ||
+ (ret = calc_clk(dev, 0x0e, &info->eng[0x0e], perflvl->vdec))) {
+ kfree(info);
+ return ERR_PTR(ret);
+ }
+
+ if (perflvl->memory) {
+ ret = calc_mem(dev, &info->mem, perflvl->memory);
+ if (ret) {
+ kfree(info);
+ return ERR_PTR(ret);
+ }
+ }
+
+ info->perflvl = perflvl;
+ return info;
+}
+
+static void
+prog_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+
+ /* program dividers at 137160/1371d0 first */
+ if (clk < 7 && !info->ssel) {
+ nv_mask(device, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv);
+ nv_wr32(device, 0x137160 + (clk * 0x04), info->dsrc);
+ }
+
+ /* switch clock to non-pll mode */
+ nv_mask(device, 0x137100, (1 << clk), 0x00000000);
+ nv_wait(device, 0x137100, (1 << clk), 0x00000000);
+
+ /* reprogram pll */
+ if (clk < 7) {
+ /* make sure it's disabled first... */
+ u32 base = 0x137000 + (clk * 0x20);
+ u32 ctrl = nv_rd32(device, base + 0x00);
+ if (ctrl & 0x00000001) {
+ nv_mask(device, base + 0x00, 0x00000004, 0x00000000);
+ nv_mask(device, base + 0x00, 0x00000001, 0x00000000);
+ }
+ /* program it to new values, if necessary */
+ if (info->ssel) {
+ nv_wr32(device, base + 0x04, info->coef);
+ nv_mask(device, base + 0x00, 0x00000001, 0x00000001);
+ nv_wait(device, base + 0x00, 0x00020000, 0x00020000);
+ nv_mask(device, base + 0x00, 0x00020004, 0x00000004);
+ }
+ }
+
+ /* select pll/non-pll mode, and program final clock divider */
+ nv_mask(device, 0x137100, (1 << clk), info->ssel);
+ nv_wait(device, 0x137100, (1 << clk), info->ssel);
+ nv_mask(device, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv);
+}
+
+static void
+mclk_precharge(struct nouveau_mem_exec_func *exec)
+{
+}
+
+static void
+mclk_refresh(struct nouveau_mem_exec_func *exec)
+{
+}
+
+static void
+mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x10f210, enable ? 0x80000000 : 0x00000000);
+}
+
+static void
+mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable)
+{
+}
+
+static void
+mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec)
+{
+ udelay((nsec + 500) / 1000);
+}
+
+static u32
+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 (mr <= 1)
+ return nv_rd32(device, 0x10f300 + ((mr - 0) * 4));
+ return nv_rd32(device, 0x10f320 + ((mr - 2) * 4));
+ } else {
+ if (mr == 0)
+ return nv_rd32(device, 0x10f300 + (mr * 4));
+ else
+ if (mr <= 7)
+ return nv_rd32(device, 0x10f32c + (mr * 4));
+ return nv_rd32(device, 0x10f34c);
+ }
+}
+
+static void
+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 (mr <= 1) {
+ nv_wr32(device, 0x10f300 + ((mr - 0) * 4), data);
+ 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)
+ nv_wr32(device, 0x10f328 + ((mr - 2) * 4), data);
+ }
+ } else {
+ if (mr == 0) nv_wr32(device, 0x10f300 + (mr * 4), data);
+ else if (mr <= 7) nv_wr32(device, 0x10f32c + (mr * 4), data);
+ else if (mr == 15) nv_wr32(device, 0x10f34c, data);
+ }
+}
+
+static void
+mclk_clock_set(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nvc0_pm_state *info = exec->priv;
+ u32 ctrl = nv_rd32(device, 0x132000);
+
+ nv_wr32(device, 0x137360, 0x00000001);
+ nv_wr32(device, 0x137370, 0x00000000);
+ nv_wr32(device, 0x137380, 0x00000000);
+ if (ctrl & 0x00000001)
+ nv_wr32(device, 0x132000, (ctrl &= ~0x00000001));
+
+ nv_wr32(device, 0x132004, info->mem.coef);
+ nv_wr32(device, 0x132000, (ctrl |= 0x00000001));
+ nv_wait(device, 0x137390, 0x00000002, 0x00000002);
+ nv_wr32(device, 0x132018, 0x00005000);
+
+ nv_wr32(device, 0x137370, 0x00000001);
+ nv_wr32(device, 0x137380, 0x00000001);
+ nv_wr32(device, 0x137360, 0x00000000);
+}
+
+static void
+mclk_timing_set(struct nouveau_mem_exec_func *exec)
+{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nvc0_pm_state *info = exec->priv;
+ struct nouveau_pm_level *perflvl = info->perflvl;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ nv_wr32(device, 0x10f290 + (i * 4), perflvl->timing.reg[i]);
+}
+
+static void
+prog_mem(struct drm_device *dev, struct nvc0_pm_state *info)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_mem_exec_func exec = {
+ .dev = dev,
+ .precharge = mclk_precharge,
+ .refresh = mclk_refresh,
+ .refresh_auto = mclk_refresh_auto,
+ .refresh_self = mclk_refresh_self,
+ .wait = mclk_wait,
+ .mrg = mclk_mrg,
+ .mrs = mclk_mrs,
+ .clock_set = mclk_clock_set,
+ .timing_set = mclk_timing_set,
+ .priv = info
+ };
+
+ if (device->chipset < 0xd0)
+ nv_wr32(device, 0x611200, 0x00003300);
+ else
+ nv_wr32(device, 0x62c000, 0x03030000);
+
+ nouveau_mem_exec(&exec, info->perflvl);
+
+ if (device->chipset < 0xd0)
+ nv_wr32(device, 0x611200, 0x00003330);
+ else
+ nv_wr32(device, 0x62c000, 0x03030300);
+}
+int
+nvc0_pm_clocks_set(struct drm_device *dev, void *data)
+{
+ struct nvc0_pm_state *info = data;
+ int i;
+
+ if (info->mem.coef)
+ prog_mem(dev, info);
+
+ for (i = 0; i < 16; i++) {
+ if (!info->eng[i].freq)
+ continue;
+ prog_clk(dev, i, &info->eng[i]);
+ }
+
+ kfree(info);
+ return 0;
+}
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 6c220cd..20c41e7 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -5,7 +5,6 @@ config DRM_OMAP
depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
depends on OMAP2_DSS
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 701c4c1..acf6678 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -664,9 +664,8 @@ static int omap_dmm_probe(struct platform_device *dev)
}
/* set dma mask for device */
- ret = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
- if (ret)
- goto fail;
+ /* NOTE: this is a workaround for the hwmod not initializing properly */
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index e7fa3cd..2603d90 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -620,6 +620,7 @@ static struct drm_driver omap_drm_driver = {
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = omap_gem_prime_export,
.gem_prime_import = omap_gem_prime_import,
+ .gem_init_object = omap_gem_init_object,
.gem_free_object = omap_gem_free_object,
.gem_vm_ops = &omap_gem_vm_ops,
.dumb_create = omap_gem_dumb_create,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 0784769..30b95b7 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -220,6 +220,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
int omap_gem_new_handle(struct drm_device *dev, struct drm_file *file,
union omap_gem_size gsize, uint32_t flags, uint32_t *handle);
void omap_gem_free_object(struct drm_gem_object *obj);
+int omap_gem_init_object(struct drm_gem_object *obj);
void *omap_gem_vaddr(struct drm_gem_object *obj);
int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 5aec3e8..533f6eb 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1274,6 +1274,11 @@ unlock:
return ret;
}
+int omap_gem_init_object(struct drm_gem_object *obj)
+{
+ return -EINVAL; /* unused */
+}
+
/* don't call directly.. called from GEM core when it is time to actually
* free the object..
*/
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index cb85860..9263db1 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -261,7 +261,7 @@ int omap_drm_irq_install(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex);
return -EBUSY;
}
- dev->irq_enabled = true;
+ dev->irq_enabled = 1;
mutex_unlock(&dev->struct_mutex);
/* Before installing handler */
@@ -272,7 +272,7 @@ int omap_drm_irq_install(struct drm_device *dev)
if (ret < 0) {
mutex_lock(&dev->struct_mutex);
- dev->irq_enabled = false;
+ dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
return ret;
}
@@ -283,7 +283,7 @@ int omap_drm_irq_install(struct drm_device *dev)
if (ret < 0) {
mutex_lock(&dev->struct_mutex);
- dev->irq_enabled = false;
+ dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
dispc_free_irq(dev);
}
@@ -294,12 +294,11 @@ int omap_drm_irq_install(struct drm_device *dev)
int omap_drm_irq_uninstall(struct drm_device *dev)
{
unsigned long irqflags;
- bool irq_enabled;
- int i;
+ int irq_enabled, i;
mutex_lock(&dev->struct_mutex);
irq_enabled = dev->irq_enabled;
- dev->irq_enabled = false;
+ dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
/*
@@ -308,9 +307,9 @@ int omap_drm_irq_uninstall(struct drm_device *dev)
if (dev->num_crtcs) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
for (i = 0; i < dev->num_crtcs; i++) {
- DRM_WAKEUP(&dev->vblank[i].queue);
- dev->vblank[i].enabled = false;
- dev->vblank[i].last =
+ DRM_WAKEUP(&dev->vbl_queue[i]);
+ dev->vblank_enabled[i] = 0;
+ dev->last_vblank[i] =
dev->driver->get_vblank_counter(dev, i);
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
diff --git a/drivers/gpu/drm/qxl/Kconfig b/drivers/gpu/drm/qxl/Kconfig
index 037d324..d6c1279 100644
--- a/drivers/gpu/drm/qxl/Kconfig
+++ b/drivers/gpu/drm/qxl/Kconfig
@@ -6,7 +6,6 @@ config DRM_QXL
select FB_SYS_IMAGEBLIT
select FB_DEFERRED_IO
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_TTM
help
QXL virtual GPU for Spice virtualization desktop integration. Do not enable this driver unless your distro ships a corresponding X.org QXL driver that can handle kernel modesetting.
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 5e827c2..835caba 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -107,17 +107,10 @@ void qxl_display_read_client_monitors_config(struct qxl_device *qdev)
qxl_io_log(qdev, "failed crc check for client_monitors_config,"
" retrying\n");
}
-
- if (!drm_helper_hpd_irq_event(qdev->ddev)) {
- /* notify that the monitor configuration changed, to
- adjust at the arbitrary resolution */
- drm_kms_helper_hotplug_event(qdev->ddev);
- }
+ drm_helper_hpd_irq_event(qdev->ddev);
}
-static int qxl_add_monitors_config_modes(struct drm_connector *connector,
- unsigned *pwidth,
- unsigned *pheight)
+static int qxl_add_monitors_config_modes(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct qxl_device *qdev = dev->dev_private;
@@ -133,15 +126,11 @@ static int qxl_add_monitors_config_modes(struct drm_connector *connector,
mode = drm_cvt_mode(dev, head->width, head->height, 60, false, false,
false);
mode->type |= DRM_MODE_TYPE_PREFERRED;
- *pwidth = head->width;
- *pheight = head->height;
drm_mode_probed_add(connector, mode);
return 1;
}
-static int qxl_add_common_modes(struct drm_connector *connector,
- unsigned pwidth,
- unsigned pheight)
+static int qxl_add_common_modes(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode = NULL;
@@ -170,9 +159,12 @@ static int qxl_add_common_modes(struct drm_connector *connector,
};
for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
+ if (common_modes[i].w < 320 || common_modes[i].h < 200)
+ continue;
+
mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h,
60, false, false, false);
- if (common_modes[i].w == pwidth && common_modes[i].h == pheight)
+ if (common_modes[i].w == 1024 && common_modes[i].h == 768)
mode->type |= DRM_MODE_TYPE_PREFERRED;
drm_mode_probed_add(connector, mode);
}
@@ -728,18 +720,16 @@ static int qxl_conn_get_modes(struct drm_connector *connector)
{
int ret = 0;
struct qxl_device *qdev = connector->dev->dev_private;
- unsigned pwidth = 1024;
- unsigned pheight = 768;
DRM_DEBUG_KMS("monitors_config=%p\n", qdev->monitors_config);
/* TODO: what should we do here? only show the configured modes for the
* device, or allow the full list, or both? */
if (qdev->monitors_config && qdev->monitors_config->count) {
- ret = qxl_add_monitors_config_modes(connector, &pwidth, &pheight);
+ ret = qxl_add_monitors_config_modes(connector);
if (ret < 0)
return ret;
}
- ret += qxl_add_common_modes(connector, pwidth, pheight);
+ ret += qxl_add_common_modes(connector);
return ret;
}
@@ -803,10 +793,7 @@ static enum drm_connector_status qxl_conn_detect(
qdev->client_monitors_config->count > output->index &&
qxl_head_enabled(&qdev->client_monitors_config->heads[output->index]));
- DRM_DEBUG("#%d connected: %d\n", output->index, connected);
- if (!connected)
- qxl_monitors_config_set(qdev, output->index, 0, 0, 0, 0, 0);
-
+ DRM_DEBUG("\n");
return connected ? connector_status_connected
: connector_status_disconnected;
}
@@ -848,21 +835,8 @@ static const struct drm_encoder_funcs qxl_enc_funcs = {
.destroy = qxl_enc_destroy,
};
-static int qxl_mode_create_hotplug_mode_update_property(struct qxl_device *qdev)
-{
- if (qdev->hotplug_mode_update_property)
- return 0;
-
- qdev->hotplug_mode_update_property =
- drm_property_create_range(qdev->ddev, DRM_MODE_PROP_IMMUTABLE,
- "hotplug_mode_update", 0, 1);
-
- return 0;
-}
-
static int qdev_output_init(struct drm_device *dev, int num_output)
{
- struct qxl_device *qdev = dev->dev_private;
struct qxl_output *qxl_output;
struct drm_connector *connector;
struct drm_encoder *encoder;
@@ -889,8 +863,6 @@ static int qdev_output_init(struct drm_device *dev, int num_output)
drm_encoder_helper_add(encoder, &qxl_enc_helper_funcs);
drm_connector_helper_add(connector, &qxl_connector_helper_funcs);
- drm_object_attach_property(&connector->base,
- qdev->hotplug_mode_update_property, 0);
drm_sysfs_connector_add(connector);
return 0;
}
@@ -1003,9 +975,6 @@ int qxl_modeset_init(struct qxl_device *qdev)
qdev->ddev->mode_config.max_height = 8192;
qdev->ddev->mode_config.fb_base = qdev->vram_base;
-
- qxl_mode_create_hotplug_mode_update_property(qdev);
-
for (i = 0 ; i < qxl_num_crtc; ++i) {
qdev_crtc_init(qdev->ddev, i);
qdev_output_init(qdev->ddev, i);
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index fee8748..514118a 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -225,6 +225,7 @@ static struct drm_driver qxl_driver = {
.debugfs_init = qxl_debugfs_init,
.debugfs_cleanup = qxl_debugfs_takedown,
#endif
+ .gem_init_object = qxl_gem_object_init,
.gem_free_object = qxl_gem_object_free,
.gem_open_object = qxl_gem_object_open,
.gem_close_object = qxl_gem_object_close,
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 7bda32f..f7c9add 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -323,8 +323,6 @@ struct qxl_device {
struct work_struct gc_work;
struct work_struct fb_work;
-
- struct drm_property *hotplug_mode_update_property;
};
/* forward declaration for QXL_INFO_IO */
@@ -414,6 +412,7 @@ int qxl_gem_object_create_with_handle(struct qxl_device *qdev,
struct qxl_surface *surf,
struct qxl_bo **qobj,
uint32_t *handle);
+int qxl_gem_object_init(struct drm_gem_object *obj);
void qxl_gem_object_free(struct drm_gem_object *gobj);
int qxl_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv);
void qxl_gem_object_close(struct drm_gem_object *obj,
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index f437b30..88722f2 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -108,7 +108,7 @@ static void qxl_fb_dirty_flush(struct fb_info *info)
u32 x1, x2, y1, y2;
/* TODO: hard coding 32 bpp */
- int stride = qfbdev->qfb.base.pitches[0];
+ int stride = qfbdev->qfb.base.pitches[0] * 4;
x1 = qfbdev->dirty.x1;
x2 = qfbdev->dirty.x2;
diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c
index b96f0c9..1648e41 100644
--- a/drivers/gpu/drm/qxl/qxl_gem.c
+++ b/drivers/gpu/drm/qxl/qxl_gem.c
@@ -28,6 +28,12 @@
#include "qxl_drv.h"
#include "qxl_object.h"
+int qxl_gem_object_init(struct drm_gem_object *obj)
+{
+ /* we do nothings here */
+ return 0;
+}
+
void qxl_gem_object_free(struct drm_gem_object *gobj)
{
struct qxl_bo *qobj = gem_to_qxl_bo(gobj);
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index e5ca498..9e8da9e 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -120,7 +120,7 @@ int qxl_device_init(struct qxl_device *qdev,
struct pci_dev *pdev,
unsigned long flags)
{
- int r, sb;
+ int r;
qdev->dev = &pdev->dev;
qdev->ddev = ddev;
@@ -136,39 +136,21 @@ int qxl_device_init(struct qxl_device *qdev,
qdev->rom_base = pci_resource_start(pdev, 2);
qdev->rom_size = pci_resource_len(pdev, 2);
qdev->vram_base = pci_resource_start(pdev, 0);
+ qdev->surfaceram_base = pci_resource_start(pdev, 1);
+ qdev->surfaceram_size = pci_resource_len(pdev, 1);
qdev->io_base = pci_resource_start(pdev, 3);
qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0));
-
- if (pci_resource_len(pdev, 4) > 0) {
- /* 64bit surface bar present */
- sb = 4;
- qdev->surfaceram_base = pci_resource_start(pdev, sb);
- qdev->surfaceram_size = pci_resource_len(pdev, sb);
- qdev->surface_mapping =
- io_mapping_create_wc(qdev->surfaceram_base,
- qdev->surfaceram_size);
- }
- if (qdev->surface_mapping == NULL) {
- /* 64bit surface bar not present (or mapping failed) */
- sb = 1;
- qdev->surfaceram_base = pci_resource_start(pdev, sb);
- qdev->surfaceram_size = pci_resource_len(pdev, sb);
- qdev->surface_mapping =
- io_mapping_create_wc(qdev->surfaceram_base,
- qdev->surfaceram_size);
- }
-
- DRM_DEBUG_KMS("qxl: vram %llx-%llx(%dM %dk), surface %llx-%llx(%dM %dk, %s)\n",
+ qdev->surface_mapping = io_mapping_create_wc(qdev->surfaceram_base, qdev->surfaceram_size);
+ DRM_DEBUG_KMS("qxl: vram %llx-%llx(%dM %dk), surface %llx-%llx(%dM %dk)\n",
(unsigned long long)qdev->vram_base,
(unsigned long long)pci_resource_end(pdev, 0),
(int)pci_resource_len(pdev, 0) / 1024 / 1024,
(int)pci_resource_len(pdev, 0) / 1024,
(unsigned long long)qdev->surfaceram_base,
- (unsigned long long)pci_resource_end(pdev, sb),
+ (unsigned long long)pci_resource_end(pdev, 1),
(int)qdev->surfaceram_size / 1024 / 1024,
- (int)qdev->surfaceram_size / 1024,
- (sb == 4) ? "64bit" : "32bit");
+ (int)qdev->surfaceram_size / 1024);
qdev->rom = ioremap(qdev->rom_base, qdev->rom_size);
if (!qdev->rom) {
@@ -248,13 +230,9 @@ int qxl_device_init(struct qxl_device *qdev,
qdev->surfaces_mem_slot = setup_slot(qdev, 1,
(unsigned long)qdev->surfaceram_base,
(unsigned long)qdev->surfaceram_base + qdev->surfaceram_size);
- DRM_INFO("main mem slot %d [%lx,%x]\n",
- qdev->main_mem_slot,
- (unsigned long)qdev->vram_base, qdev->rom->ram_header_offset);
- DRM_INFO("surface mem slot %d [%lx,%lx]\n",
- qdev->surfaces_mem_slot,
- (unsigned long)qdev->surfaceram_base,
- (unsigned long)qdev->surfaceram_size);
+ DRM_INFO("main mem slot %d [%lx,%x)\n",
+ qdev->main_mem_slot,
+ (unsigned long)qdev->vram_base, qdev->rom->ram_header_offset);
qdev->gc_queue = create_singlethread_workqueue("qxl_gc");
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c
index 821ab7b..0109a96 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -92,7 +92,6 @@ qxl_release_free(struct qxl_device *qdev,
- DRM_FILE_OFFSET);
qxl_fence_remove_release(&bo->fence, release->id);
qxl_bo_unref(&bo);
- kfree(entry);
}
spin_lock(&qdev->release_idr_lock);
idr_remove(&qdev->release_idr, release->id);
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index c7e7e65..037786d 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -516,8 +516,6 @@ int qxl_ttm_init(struct qxl_device *qdev)
(unsigned)qdev->vram_size / (1024 * 1024));
DRM_INFO("qxl: %luM of IO pages memory ready (VRAM domain)\n",
((unsigned)num_io_pages * PAGE_SIZE) / (1024 * 1024));
- DRM_INFO("qxl: %uM of Surface memory size\n",
- (unsigned)qdev->surfaceram_size / (1024 * 1024));
if (unlikely(qdev->mman.bdev.dev_mapping == NULL))
qdev->mman.bdev.dev_mapping = qdev->ddev->dev_mapping;
r = qxl_ttm_debugfs_init(qdev);
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
index 92be50c..af10f85 100644
--- a/drivers/gpu/drm/radeon/atombios.h
+++ b/drivers/gpu/drm/radeon/atombios.h
@@ -1711,9 +1711,7 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V6
#define PIXEL_CLOCK_V6_MISC_HDMI_BPP_MASK 0x0c
#define PIXEL_CLOCK_V6_MISC_HDMI_24BPP 0x00
#define PIXEL_CLOCK_V6_MISC_HDMI_36BPP 0x04
-#define PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6 0x08 //for V6, the correct defintion for 36bpp should be 2 for 36bpp(2:1)
#define PIXEL_CLOCK_V6_MISC_HDMI_30BPP 0x08
-#define PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6 0x04 //for V6, the correct defintion for 30bpp should be 1 for 36bpp(5:4)
#define PIXEL_CLOCK_V6_MISC_HDMI_48BPP 0x0c
#define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC 0x10
#define PIXEL_CLOCK_V6_MISC_GEN_DPREFCLK 0x40
@@ -2225,7 +2223,7 @@ typedef struct _SET_VOLTAGE_PARAMETERS_V2
USHORT usVoltageLevel; // real voltage level
}SET_VOLTAGE_PARAMETERS_V2;
-// used by both SetVoltageTable v1.3 and v1.4
+
typedef struct _SET_VOLTAGE_PARAMETERS_V1_3
{
UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI
@@ -2292,36 +2290,15 @@ typedef struct _GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1
#define ATOM_GET_VOLTAGE_VID 0x00
#define ATOM_GET_VOTLAGE_INIT_SEQ 0x03
#define ATOM_GET_VOLTTAGE_PHASE_PHASE_VID 0x04
-#define ATOM_GET_VOLTAGE_SVID2 0x07 //Get SVI2 Regulator Info
-
// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state
-#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10
+#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10
+
// for SI, this state map to 0xff01 voltage state in Power Play table, which is performance state
#define ATOM_GET_VOLTAGE_STATE1_LEAKAGE_VID 0x11
-
+// undefined power state
#define ATOM_GET_VOLTAGE_STATE2_LEAKAGE_VID 0x12
#define ATOM_GET_VOLTAGE_STATE3_LEAKAGE_VID 0x13
-// New Added from CI Hawaii for GetVoltageInfoTable, input parameter structure
-typedef struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2
-{
- UCHAR ucVoltageType; // Input: To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI
- UCHAR ucVoltageMode; // Input: Indicate action: Get voltage info
- USHORT usVoltageLevel; // Input: real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) or Leakage Id
- ULONG ulSCLKFreq; // Input: when ucVoltageMode= ATOM_GET_VOLTAGE_EVV_VOLTAGE, DPM state SCLK frequency, Define in PPTable SCLK/Voltage dependence table
-}GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2;
-
-// New in GetVoltageInfo v1.2 ucVoltageMode
-#define ATOM_GET_VOLTAGE_EVV_VOLTAGE 0x09
-
-// New Added from CI Hawaii for EVV feature
-typedef struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2
-{
- USHORT usVoltageLevel; // real voltage level in unit of mv
- USHORT usVoltageId; // Voltage Id programmed in Voltage Regulator
- ULONG ulReseved;
-}GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2;
-
/****************************************************************************/
// Structures used by TVEncoderControlTable
/****************************************************************************/
@@ -3887,8 +3864,6 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT
#define PP_AC_DC_SWITCH_GPIO_PINID 60
//from SMU7.x, if ucGPIO_ID=VDDC_REGULATOR_VRHOT_GPIO_PINID in GPIO_LUTable, VRHot feature is enable
#define VDDC_VRHOT_GPIO_PINID 61
-//if ucGPIO_ID=VDDC_PCC_GPIO_PINID in GPIO_LUTable, Peak Current Control feature is enabled
-#define VDDC_PCC_GPIO_PINID 62
typedef struct _ATOM_GPIO_PIN_LUT
{
@@ -4194,10 +4169,10 @@ typedef struct _ATOM_COMMON_RECORD_HEADER
#define ATOM_OBJECT_LINK_RECORD_TYPE 18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record
#define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19
#define ATOM_ENCODER_CAP_RECORD_TYPE 20
-#define ATOM_BRACKET_LAYOUT_RECORD_TYPE 21
+
//Must be updated when new record type is added,equal to that record definition!
-#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_BRACKET_LAYOUT_RECORD_TYPE
+#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_ENCODER_CAP_RECORD_TYPE
typedef struct _ATOM_I2C_RECORD
{
@@ -4422,31 +4397,6 @@ typedef struct _ATOM_CONNECTOR_REMOTE_CAP_RECORD
USHORT usReserved;
}ATOM_CONNECTOR_REMOTE_CAP_RECORD;
-typedef struct _ATOM_CONNECTOR_LAYOUT_INFO
-{
- USHORT usConnectorObjectId;
- UCHAR ucConnectorType;
- UCHAR ucPosition;
-}ATOM_CONNECTOR_LAYOUT_INFO;
-
-// define ATOM_CONNECTOR_LAYOUT_INFO.ucConnectorType to describe the display connector size
-#define CONNECTOR_TYPE_DVI_D 1
-#define CONNECTOR_TYPE_DVI_I 2
-#define CONNECTOR_TYPE_VGA 3
-#define CONNECTOR_TYPE_HDMI 4
-#define CONNECTOR_TYPE_DISPLAY_PORT 5
-#define CONNECTOR_TYPE_MINI_DISPLAY_PORT 6
-
-typedef struct _ATOM_BRACKET_LAYOUT_RECORD
-{
- ATOM_COMMON_RECORD_HEADER sheader;
- UCHAR ucLength;
- UCHAR ucWidth;
- UCHAR ucConnNum;
- UCHAR ucReserved;
- ATOM_CONNECTOR_LAYOUT_INFO asConnInfo[1];
-}ATOM_BRACKET_LAYOUT_RECORD;
-
/****************************************************************************/
// ASIC voltage data table
/****************************************************************************/
@@ -4574,9 +4524,8 @@ typedef struct _ATOM_VOLTAGE_OBJECT_HEADER_V3{
#define VOLTAGE_OBJ_VR_I2C_INIT_SEQ 3 //VOLTAGE REGULATOR INIT sequece through I2C -> ATOM_I2C_VOLTAGE_OBJECT_V3
#define VOLTAGE_OBJ_PHASE_LUT 4 //Set Vregulator Phase lookup table ->ATOM_GPIO_VOLTAGE_OBJECT_V3
#define VOLTAGE_OBJ_SVID2 7 //Indicate voltage control by SVID2 ->ATOM_SVID2_VOLTAGE_OBJECT_V3
-#define VOLTAGE_OBJ_EVV 8
-#define VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT 0x10 //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
-#define VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT 0x11 //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT 0x10 //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT 0x11 //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
#define VOLTAGE_OBJ_HIGH1_STATE_LEAKAGE_LUT 0x12 //High1 voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
typedef struct _VOLTAGE_LUT_ENTRY_V2
@@ -4603,10 +4552,6 @@ typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3
VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff
}ATOM_I2C_VOLTAGE_OBJECT_V3;
-// ATOM_I2C_VOLTAGE_OBJECT_V3.ucVoltageControlFlag
-#define VOLTAGE_DATA_ONE_BYTE 0
-#define VOLTAGE_DATA_TWO_BYTE 1
-
typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3
{
ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; // voltage mode = VOLTAGE_OBJ_GPIO_LUT or VOLTAGE_OBJ_PHASE_LUT
@@ -4639,8 +4584,7 @@ typedef struct _ATOM_SVID2_VOLTAGE_OBJECT_V3
// 1:0 – offset trim,
USHORT usLoadLine_PSI;
// GPU GPIO pin Id to SVID2 regulator VRHot pin. possible value 0~31. 0 means GPIO0, 31 means GPIO31
- UCHAR ucSVDGpioId; //0~31 indicate GPIO0~31
- UCHAR ucSVCGpioId; //0~31 indicate GPIO0~31
+ UCHAR ucReserved[2];
ULONG ulReserved;
}ATOM_SVID2_VOLTAGE_OBJECT_V3;
@@ -4693,49 +4637,6 @@ typedef struct _ATOM_ASIC_PROFILING_INFO_V2_1
USHORT usElbVDDCI_LevelArrayOffset; // offset of 2 dimension voltage level USHORT array
}ATOM_ASIC_PROFILING_INFO_V2_1;
-typedef struct _ATOM_ASIC_PROFILING_INFO_V3_1
-{
- ATOM_COMMON_TABLE_HEADER asHeader;
- ULONG ulEvvDerateTdp;
- ULONG ulEvvDerateTdc;
- ULONG ulBoardCoreTemp;
- ULONG ulMaxVddc;
- ULONG ulMinVddc;
- ULONG ulLoadLineSlop;
- ULONG ulLeakageTemp;
- ULONG ulLeakageVoltage;
- ULONG ulCACmEncodeRange;
- ULONG ulCACmEncodeAverage;
- ULONG ulCACbEncodeRange;
- ULONG ulCACbEncodeAverage;
- ULONG ulKt_bEncodeRange;
- ULONG ulKt_bEncodeAverage;
- ULONG ulKv_mEncodeRange;
- ULONG ulKv_mEncodeAverage;
- ULONG ulKv_bEncodeRange;
- ULONG ulKv_bEncodeAverage;
- ULONG ulLkgEncodeLn_MaxDivMin;
- ULONG ulLkgEncodeMin;
- ULONG ulEfuseLogisticAlpha;
- USHORT usPowerDpm0;
- USHORT usCurrentDpm0;
- USHORT usPowerDpm1;
- USHORT usCurrentDpm1;
- USHORT usPowerDpm2;
- USHORT usCurrentDpm2;
- USHORT usPowerDpm3;
- USHORT usCurrentDpm3;
- USHORT usPowerDpm4;
- USHORT usCurrentDpm4;
- USHORT usPowerDpm5;
- USHORT usCurrentDpm5;
- USHORT usPowerDpm6;
- USHORT usCurrentDpm6;
- USHORT usPowerDpm7;
- USHORT usCurrentDpm7;
-}ATOM_ASIC_PROFILING_INFO_V3_1;
-
-
typedef struct _ATOM_POWER_SOURCE_OBJECT
{
UCHAR ucPwrSrcId; // Power source
@@ -5907,8 +5808,6 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3
#define ATOM_S7_DOS_MODE_PIXEL_DEPTHb0 0x0C
#define ATOM_S7_DOS_MODE_PIXEL_FORMATb0 0xF0
#define ATOM_S7_DOS_8BIT_DAC_ENb1 0x01
-#define ATOM_S7_ASIC_INIT_COMPLETEb1 0x02
-#define ATOM_S7_ASIC_INIT_COMPLETE_MASK 0x00000200
#define ATOM_S7_DOS_MODE_NUMBERw1 0x0FFFF
#define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT 8
@@ -6343,7 +6242,6 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE
#define _128Mx32 0x53
#define _256Mx8 0x61
#define _256Mx16 0x62
-#define _512Mx8 0x71
#define SAMSUNG 0x1
#define INFINEON 0x2
@@ -7089,10 +6987,9 @@ typedef struct _ATOM_DISP_OUT_INFO_V3
UCHAR ucMaxDispEngineNum;
UCHAR ucMaxActiveDispEngineNum;
UCHAR ucMaxPPLLNum;
- UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE
- UCHAR ucDispCaps;
- UCHAR ucReserved[2];
- ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only
+ UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE
+ UCHAR ucReserved[3];
+ ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only
}ATOM_DISP_OUT_INFO_V3;
//ucDispCaps
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 80a2012..bf87f6d 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1753,7 +1753,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
if (pll != ATOM_PPLL_INVALID)
return pll;
}
- } else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */
+ } else {
/* use the same PPLL for all monitors with the same clock */
pll = radeon_get_shared_nondp_ppll(crtc);
if (pll != ATOM_PPLL_INVALID)
@@ -1910,21 +1910,6 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
int i;
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
- if (crtc->fb) {
- int r;
- struct radeon_framebuffer *radeon_fb;
- struct radeon_bo *rbo;
-
- radeon_fb = to_radeon_framebuffer(crtc->fb);
- rbo = gem_to_radeon_bo(radeon_fb->obj);
- r = radeon_bo_reserve(rbo, false);
- if (unlikely(r))
- DRM_ERROR("failed to reserve rbo before unpin\n");
- else {
- radeon_bo_unpin(rbo);
- radeon_bo_unreserve(rbo);
- }
- }
/* disable the GRPH */
if (ASIC_IS_DCE4(rdev))
WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 0);
@@ -1955,9 +1940,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
break;
case ATOM_PPLL0:
/* disable the ppll */
- if ((rdev->family == CHIP_ARUBA) ||
- (rdev->family == CHIP_BONAIRE) ||
- (rdev->family == CHIP_HAWAII))
+ if ((rdev->family == CHIP_ARUBA) || (rdev->family == CHIP_BONAIRE))
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
break;
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index fb3ae07..0088541 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -690,7 +690,8 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
/* set the lane count on the sink */
tmp = dp_info->dp_lane_count;
- if (drm_dp_enhanced_frame_cap(dp_info->dpcd))
+ if (dp_info->dpcd[DP_DPCD_REV] >= 0x11 &&
+ dp_info->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)
tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp);
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index a42d615..5e891b2 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -213,7 +213,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
props.type = BACKLIGHT_RAW;
snprintf(bl_name, sizeof(bl_name),
"radeon_bl%d", dev->primary->index);
- bd = backlight_device_register(bl_name, drm_connector->kdev,
+ bd = backlight_device_register(bl_name, &drm_connector->kdev,
pdata, &radeon_atom_backlight_ops, &props);
if (IS_ERR(bd)) {
DRM_ERROR("Backlight registration failed\n");
@@ -1662,11 +1662,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
/* enable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
} else {
/* setup and enable the encoder and transmitter */
atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+ /* some dce3.x boards have a bug in their transmitter control table.
+ * ACTION_ENABLE_OUTPUT can probably be dropped since ACTION_ENABLE
+ * does the same thing and more.
+ */
+ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) &&
+ (rdev->family != CHIP_RS780) && (rdev->family != CHIP_RS880))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
}
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
@@ -1684,11 +1692,16 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- if (ASIC_IS_DCE4(rdev)) {
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+ /* disable the transmitter */
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+ } else if (ASIC_IS_DCE4(rdev)) {
/* disable the transmitter */
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
} else {
/* disable the encoder and transmitter */
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
}
@@ -2397,15 +2410,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
/* this is needed for the pll/ss setup to work correctly in some cases */
atombios_set_encoder_crtc_source(encoder);
- /* set up the FMT blocks */
- if (ASIC_IS_DCE8(rdev))
- dce8_program_fmt(encoder);
- else if (ASIC_IS_DCE4(rdev))
- dce4_program_fmt(encoder);
- else if (ASIC_IS_DCE3(rdev))
- dce3_program_fmt(encoder);
- else if (ASIC_IS_AVIVO(rdev))
- avivo_program_fmt(encoder);
}
static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c
index f685035dbe..deaf98c 100644
--- a/drivers/gpu/drm/radeon/atombios_i2c.c
+++ b/drivers/gpu/drm/radeon/atombios_i2c.c
@@ -44,7 +44,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction);
unsigned char *base;
- u16 out = cpu_to_le16(0);
+ u16 out;
memset(&args, 0, sizeof(args));
@@ -55,14 +55,9 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 3)\n", num);
return -EINVAL;
}
- if (buf == NULL)
- args.ucRegIndex = 0;
- else
- args.ucRegIndex = buf[0];
- if (num)
- num--;
- if (num)
- memcpy(&out, &buf[1], num);
+ args.ucRegIndex = buf[0];
+ if (num > 1)
+ memcpy(&out, &buf[1], num - 1);
args.lpI2CDataOut = cpu_to_le16(out);
} else {
if (num > ATOM_MAX_HW_I2C_READ) {
@@ -99,14 +94,14 @@ int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
struct i2c_msg *p;
int i, remaining, current_count, buffer_offset, max_bytes, ret;
- u8 flags;
+ u8 buf = 0, flags;
/* check for bus probe */
p = &msgs[0];
if ((num == 1) && (p->len == 0)) {
ret = radeon_process_i2c_ch(i2c,
p->addr, HW_I2C_WRITE,
- NULL, 0);
+ &buf, 1);
if (ret)
return ret;
else
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index 1ed4799..51e947a 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -40,20 +40,6 @@
#define VOLTAGE_VID_OFFSET_SCALE1 625
#define VOLTAGE_VID_OFFSET_SCALE2 100
-static const struct ci_pt_defaults defaults_hawaii_xt =
-{
- 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0xB0000,
- { 0x84, 0x0, 0x0, 0x7F, 0x0, 0x0, 0x5A, 0x60, 0x51, 0x8E, 0x79, 0x6B, 0x5F, 0x90, 0x79 },
- { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC }
-};
-
-static const struct ci_pt_defaults defaults_hawaii_pro =
-{
- 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0x65062,
- { 0x93, 0x0, 0x0, 0x97, 0x0, 0x0, 0x6B, 0x60, 0x51, 0x95, 0x79, 0x6B, 0x5F, 0x90, 0x79 },
- { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC }
-};
-
static const struct ci_pt_defaults defaults_bonaire_xt =
{
1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000,
@@ -201,38 +187,22 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev)
struct ci_power_info *pi = ci_get_pi(rdev);
switch (rdev->pdev->device) {
- case 0x6650:
- case 0x6658:
- case 0x665C:
- default:
+ case 0x6650:
+ case 0x6658:
+ case 0x665C:
+ default:
pi->powertune_defaults = &defaults_bonaire_xt;
break;
- case 0x6651:
- case 0x665D:
+ case 0x6651:
+ case 0x665D:
pi->powertune_defaults = &defaults_bonaire_pro;
break;
- case 0x6640:
+ case 0x6640:
pi->powertune_defaults = &defaults_saturn_xt;
break;
- case 0x6641:
+ case 0x6641:
pi->powertune_defaults = &defaults_saturn_pro;
break;
- case 0x67B8:
- case 0x67B0:
- case 0x67A0:
- case 0x67A1:
- case 0x67A2:
- case 0x67A8:
- case 0x67A9:
- case 0x67AA:
- case 0x67B9:
- case 0x67BE:
- pi->powertune_defaults = &defaults_hawaii_xt;
- break;
- case 0x67BA:
- case 0x67B1:
- pi->powertune_defaults = &defaults_hawaii_pro;
- break;
}
pi->dte_tj_offset = 0;
@@ -5172,15 +5142,9 @@ int ci_dpm_init(struct radeon_device *rdev)
rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
- if (rdev->family == CHIP_HAWAII) {
- pi->thermal_temp_setting.temperature_low = 94500;
- pi->thermal_temp_setting.temperature_high = 95000;
- pi->thermal_temp_setting.temperature_shutdown = 104000;
- } else {
- pi->thermal_temp_setting.temperature_low = 99500;
- pi->thermal_temp_setting.temperature_high = 100000;
- pi->thermal_temp_setting.temperature_shutdown = 104000;
- }
+ pi->thermal_temp_setting.temperature_low = 99500;
+ pi->thermal_temp_setting.temperature_high = 100000;
+ pi->thermal_temp_setting.temperature_shutdown = 104000;
pi->uvd_enabled = false;
diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c
index 9c745dd..252e10a 100644
--- a/drivers/gpu/drm/radeon/ci_smc.c
+++ b/drivers/gpu/drm/radeon/ci_smc.c
@@ -217,10 +217,6 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
ucode_start_address = BONAIRE_SMC_UCODE_START;
ucode_size = BONAIRE_SMC_UCODE_SIZE;
break;
- case CHIP_HAWAII:
- ucode_start_address = HAWAII_SMC_UCODE_START;
- ucode_size = HAWAII_SMC_UCODE_SIZE;
- break;
default:
DRM_ERROR("unknown asic in smc ucode loader\n");
BUG();
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index b43a3a3..9cd2bc9 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -41,14 +41,6 @@ MODULE_FIRMWARE("radeon/BONAIRE_mc.bin");
MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin");
MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin");
MODULE_FIRMWARE("radeon/BONAIRE_smc.bin");
-MODULE_FIRMWARE("radeon/HAWAII_pfp.bin");
-MODULE_FIRMWARE("radeon/HAWAII_me.bin");
-MODULE_FIRMWARE("radeon/HAWAII_ce.bin");
-MODULE_FIRMWARE("radeon/HAWAII_mec.bin");
-MODULE_FIRMWARE("radeon/HAWAII_mc.bin");
-MODULE_FIRMWARE("radeon/HAWAII_rlc.bin");
-MODULE_FIRMWARE("radeon/HAWAII_sdma.bin");
-MODULE_FIRMWARE("radeon/HAWAII_smc.bin");
MODULE_FIRMWARE("radeon/KAVERI_pfp.bin");
MODULE_FIRMWARE("radeon/KAVERI_me.bin");
MODULE_FIRMWARE("radeon/KAVERI_ce.bin");
@@ -75,6 +67,11 @@ extern void si_init_uvd_internal_cg(struct radeon_device *rdev);
extern int cik_sdma_resume(struct radeon_device *rdev);
extern void cik_sdma_enable(struct radeon_device *rdev, bool enable);
extern void cik_sdma_fini(struct radeon_device *rdev);
+extern void cik_sdma_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
static void cik_rlc_stop(struct radeon_device *rdev);
static void cik_pcie_gen3_enable(struct radeon_device *rdev);
static void cik_program_aspm(struct radeon_device *rdev);
@@ -1305,171 +1302,6 @@ static const u32 kalindi_mgcg_cgcg_init[] =
0xd80c, 0xff000ff0, 0x00000100
};
-static const u32 hawaii_golden_spm_registers[] =
-{
- 0x30800, 0xe0ffffff, 0xe0000000
-};
-
-static const u32 hawaii_golden_common_registers[] =
-{
- 0x30800, 0xffffffff, 0xe0000000,
- 0x28350, 0xffffffff, 0x3a00161a,
- 0x28354, 0xffffffff, 0x0000002e,
- 0x9a10, 0xffffffff, 0x00018208,
- 0x98f8, 0xffffffff, 0x12011003
-};
-
-static const u32 hawaii_golden_registers[] =
-{
- 0x3354, 0x00000333, 0x00000333,
- 0x9a10, 0x00010000, 0x00058208,
- 0x9830, 0xffffffff, 0x00000000,
- 0x9834, 0xf00fffff, 0x00000400,
- 0x9838, 0x0002021c, 0x00020200,
- 0xc78, 0x00000080, 0x00000000,
- 0x5bb0, 0x000000f0, 0x00000070,
- 0x5bc0, 0xf0311fff, 0x80300000,
- 0x350c, 0x00810000, 0x408af000,
- 0x7030, 0x31000111, 0x00000011,
- 0x2f48, 0x73773777, 0x12010001,
- 0x2120, 0x0000007f, 0x0000001b,
- 0x21dc, 0x00007fb6, 0x00002191,
- 0x3628, 0x0000003f, 0x0000000a,
- 0x362c, 0x0000003f, 0x0000000a,
- 0x2ae4, 0x00073ffe, 0x000022a2,
- 0x240c, 0x000007ff, 0x00000000,
- 0x8bf0, 0x00002001, 0x00000001,
- 0x8b24, 0xffffffff, 0x00ffffff,
- 0x30a04, 0x0000ff0f, 0x00000000,
- 0x28a4c, 0x07ffffff, 0x06000000,
- 0x3e78, 0x00000001, 0x00000002,
- 0xc768, 0x00000008, 0x00000008,
- 0xc770, 0x00000f00, 0x00000800,
- 0xc774, 0x00000f00, 0x00000800,
- 0xc798, 0x00ffffff, 0x00ff7fbf,
- 0xc79c, 0x00ffffff, 0x00ff7faf,
- 0x8c00, 0x000000ff, 0x00000800,
- 0xe40, 0x00001fff, 0x00001fff,
- 0x9060, 0x0000007f, 0x00000020,
- 0x9508, 0x00010000, 0x00010000,
- 0xae00, 0x00100000, 0x000ff07c,
- 0xac14, 0x000003ff, 0x0000000f,
- 0xac10, 0xffffffff, 0x7564fdec,
- 0xac0c, 0xffffffff, 0x3120b9a8,
- 0xac08, 0x20000000, 0x0f9c0000
-};
-
-static const u32 hawaii_mgcg_cgcg_init[] =
-{
- 0xc420, 0xffffffff, 0xfffffffd,
- 0x30800, 0xffffffff, 0xe0000000,
- 0x3c2a0, 0xffffffff, 0x00000100,
- 0x3c208, 0xffffffff, 0x00000100,
- 0x3c2c0, 0xffffffff, 0x00000100,
- 0x3c2c8, 0xffffffff, 0x00000100,
- 0x3c2c4, 0xffffffff, 0x00000100,
- 0x55e4, 0xffffffff, 0x00200100,
- 0x3c280, 0xffffffff, 0x00000100,
- 0x3c214, 0xffffffff, 0x06000100,
- 0x3c220, 0xffffffff, 0x00000100,
- 0x3c218, 0xffffffff, 0x06000100,
- 0x3c204, 0xffffffff, 0x00000100,
- 0x3c2e0, 0xffffffff, 0x00000100,
- 0x3c224, 0xffffffff, 0x00000100,
- 0x3c200, 0xffffffff, 0x00000100,
- 0x3c230, 0xffffffff, 0x00000100,
- 0x3c234, 0xffffffff, 0x00000100,
- 0x3c250, 0xffffffff, 0x00000100,
- 0x3c254, 0xffffffff, 0x00000100,
- 0x3c258, 0xffffffff, 0x00000100,
- 0x3c25c, 0xffffffff, 0x00000100,
- 0x3c260, 0xffffffff, 0x00000100,
- 0x3c27c, 0xffffffff, 0x00000100,
- 0x3c278, 0xffffffff, 0x00000100,
- 0x3c210, 0xffffffff, 0x06000100,
- 0x3c290, 0xffffffff, 0x00000100,
- 0x3c274, 0xffffffff, 0x00000100,
- 0x3c2b4, 0xffffffff, 0x00000100,
- 0x3c2b0, 0xffffffff, 0x00000100,
- 0x3c270, 0xffffffff, 0x00000100,
- 0x30800, 0xffffffff, 0xe0000000,
- 0x3c020, 0xffffffff, 0x00010000,
- 0x3c024, 0xffffffff, 0x00030002,
- 0x3c028, 0xffffffff, 0x00040007,
- 0x3c02c, 0xffffffff, 0x00060005,
- 0x3c030, 0xffffffff, 0x00090008,
- 0x3c034, 0xffffffff, 0x00010000,
- 0x3c038, 0xffffffff, 0x00030002,
- 0x3c03c, 0xffffffff, 0x00040007,
- 0x3c040, 0xffffffff, 0x00060005,
- 0x3c044, 0xffffffff, 0x00090008,
- 0x3c048, 0xffffffff, 0x00010000,
- 0x3c04c, 0xffffffff, 0x00030002,
- 0x3c050, 0xffffffff, 0x00040007,
- 0x3c054, 0xffffffff, 0x00060005,
- 0x3c058, 0xffffffff, 0x00090008,
- 0x3c05c, 0xffffffff, 0x00010000,
- 0x3c060, 0xffffffff, 0x00030002,
- 0x3c064, 0xffffffff, 0x00040007,
- 0x3c068, 0xffffffff, 0x00060005,
- 0x3c06c, 0xffffffff, 0x00090008,
- 0x3c070, 0xffffffff, 0x00010000,
- 0x3c074, 0xffffffff, 0x00030002,
- 0x3c078, 0xffffffff, 0x00040007,
- 0x3c07c, 0xffffffff, 0x00060005,
- 0x3c080, 0xffffffff, 0x00090008,
- 0x3c084, 0xffffffff, 0x00010000,
- 0x3c088, 0xffffffff, 0x00030002,
- 0x3c08c, 0xffffffff, 0x00040007,
- 0x3c090, 0xffffffff, 0x00060005,
- 0x3c094, 0xffffffff, 0x00090008,
- 0x3c098, 0xffffffff, 0x00010000,
- 0x3c09c, 0xffffffff, 0x00030002,
- 0x3c0a0, 0xffffffff, 0x00040007,
- 0x3c0a4, 0xffffffff, 0x00060005,
- 0x3c0a8, 0xffffffff, 0x00090008,
- 0x3c0ac, 0xffffffff, 0x00010000,
- 0x3c0b0, 0xffffffff, 0x00030002,
- 0x3c0b4, 0xffffffff, 0x00040007,
- 0x3c0b8, 0xffffffff, 0x00060005,
- 0x3c0bc, 0xffffffff, 0x00090008,
- 0x3c0c0, 0xffffffff, 0x00010000,
- 0x3c0c4, 0xffffffff, 0x00030002,
- 0x3c0c8, 0xffffffff, 0x00040007,
- 0x3c0cc, 0xffffffff, 0x00060005,
- 0x3c0d0, 0xffffffff, 0x00090008,
- 0x3c0d4, 0xffffffff, 0x00010000,
- 0x3c0d8, 0xffffffff, 0x00030002,
- 0x3c0dc, 0xffffffff, 0x00040007,
- 0x3c0e0, 0xffffffff, 0x00060005,
- 0x3c0e4, 0xffffffff, 0x00090008,
- 0x3c0e8, 0xffffffff, 0x00010000,
- 0x3c0ec, 0xffffffff, 0x00030002,
- 0x3c0f0, 0xffffffff, 0x00040007,
- 0x3c0f4, 0xffffffff, 0x00060005,
- 0x3c0f8, 0xffffffff, 0x00090008,
- 0xc318, 0xffffffff, 0x00020200,
- 0x3350, 0xffffffff, 0x00000200,
- 0x15c0, 0xffffffff, 0x00000400,
- 0x55e8, 0xffffffff, 0x00000000,
- 0x2f50, 0xffffffff, 0x00000902,
- 0x3c000, 0xffffffff, 0x96940200,
- 0x8708, 0xffffffff, 0x00900100,
- 0xc424, 0xffffffff, 0x0020003f,
- 0x38, 0xffffffff, 0x0140001c,
- 0x3c, 0x000f0000, 0x000f0000,
- 0x220, 0xffffffff, 0xc060000c,
- 0x224, 0xc0000fff, 0x00000100,
- 0xf90, 0xffffffff, 0x00000100,
- 0xf98, 0x00000101, 0x00000000,
- 0x20a8, 0xffffffff, 0x00000104,
- 0x55e4, 0xff000fff, 0x00000100,
- 0x30cc, 0xc0000fff, 0x00000104,
- 0xc1e4, 0x00000001, 0x00000001,
- 0xd00c, 0xff000ff0, 0x00000100,
- 0xd80c, 0xff000ff0, 0x00000100
-};
-
static void cik_init_golden_registers(struct radeon_device *rdev)
{
switch (rdev->family) {
@@ -1515,20 +1347,6 @@ static void cik_init_golden_registers(struct radeon_device *rdev)
spectre_golden_spm_registers,
(const u32)ARRAY_SIZE(spectre_golden_spm_registers));
break;
- case CHIP_HAWAII:
- radeon_program_register_sequence(rdev,
- hawaii_mgcg_cgcg_init,
- (const u32)ARRAY_SIZE(hawaii_mgcg_cgcg_init));
- radeon_program_register_sequence(rdev,
- hawaii_golden_registers,
- (const u32)ARRAY_SIZE(hawaii_golden_registers));
- radeon_program_register_sequence(rdev,
- hawaii_golden_common_registers,
- (const u32)ARRAY_SIZE(hawaii_golden_common_registers));
- radeon_program_register_sequence(rdev,
- hawaii_golden_spm_registers,
- (const u32)ARRAY_SIZE(hawaii_golden_spm_registers));
- break;
default:
break;
}
@@ -1560,17 +1378,17 @@ u32 cik_get_xclk(struct radeon_device *rdev)
* cik_mm_rdoorbell - read a doorbell dword
*
* @rdev: radeon_device pointer
- * @index: doorbell index
+ * @offset: byte offset into the aperture
*
* Returns the value in the doorbell aperture at the
- * requested doorbell index (CIK).
+ * requested offset (CIK).
*/
-u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index)
+u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 offset)
{
- if (index < rdev->doorbell.num_doorbells) {
- return readl(rdev->doorbell.ptr + index);
+ if (offset < rdev->doorbell.size) {
+ return readl(((void __iomem *)rdev->doorbell.ptr) + offset);
} else {
- DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
+ DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", offset);
return 0;
}
}
@@ -1579,18 +1397,18 @@ u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index)
* cik_mm_wdoorbell - write a doorbell dword
*
* @rdev: radeon_device pointer
- * @index: doorbell index
+ * @offset: byte offset into the aperture
* @v: value to write
*
* Writes @v to the doorbell aperture at the
- * requested doorbell index (CIK).
+ * requested offset (CIK).
*/
-void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v)
+void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v)
{
- if (index < rdev->doorbell.num_doorbells) {
- writel(v, rdev->doorbell.ptr + index);
+ if (offset < rdev->doorbell.size) {
+ writel(v, ((void __iomem *)rdev->doorbell.ptr) + offset);
} else {
- DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
+ DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", offset);
}
}
@@ -1636,35 +1454,6 @@ static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
{0x0000009f, 0x00b48000}
};
-#define HAWAII_IO_MC_REGS_SIZE 22
-
-static const u32 hawaii_io_mc_regs[HAWAII_IO_MC_REGS_SIZE][2] =
-{
- {0x0000007d, 0x40000000},
- {0x0000007e, 0x40180304},
- {0x0000007f, 0x0000ff00},
- {0x00000081, 0x00000000},
- {0x00000083, 0x00000800},
- {0x00000086, 0x00000000},
- {0x00000087, 0x00000100},
- {0x00000088, 0x00020100},
- {0x00000089, 0x00000000},
- {0x0000008b, 0x00040000},
- {0x0000008c, 0x00000100},
- {0x0000008e, 0xff010000},
- {0x00000090, 0xffffefff},
- {0x00000091, 0xfff3efff},
- {0x00000092, 0xfff3efbf},
- {0x00000093, 0xf7ffffff},
- {0x00000094, 0xffffff7f},
- {0x00000095, 0x00000fff},
- {0x00000096, 0x00116fff},
- {0x00000097, 0x60010000},
- {0x00000098, 0x10010000},
- {0x0000009f, 0x00c79000}
-};
-
-
/**
* cik_srbm_select - select specific register instances
*
@@ -1709,17 +1498,11 @@ static int ci_mc_load_microcode(struct radeon_device *rdev)
switch (rdev->family) {
case CHIP_BONAIRE:
+ default:
io_mc_regs = (u32 *)&bonaire_io_mc_regs;
ucode_size = CIK_MC_UCODE_SIZE;
regs_size = BONAIRE_IO_MC_REGS_SIZE;
break;
- case CHIP_HAWAII:
- io_mc_regs = (u32 *)&hawaii_io_mc_regs;
- ucode_size = HAWAII_MC_UCODE_SIZE;
- regs_size = HAWAII_IO_MC_REGS_SIZE;
- break;
- default:
- return -EINVAL;
}
running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
@@ -1781,8 +1564,8 @@ static int cik_init_microcode(struct radeon_device *rdev)
{
const char *chip_name;
size_t pfp_req_size, me_req_size, ce_req_size,
- mec_req_size, rlc_req_size, mc_req_size = 0,
- sdma_req_size, smc_req_size = 0;
+ mec_req_size, rlc_req_size, mc_req_size,
+ sdma_req_size, smc_req_size;
char fw_name[30];
int err;
@@ -1800,17 +1583,6 @@ static int cik_init_microcode(struct radeon_device *rdev)
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4);
break;
- case CHIP_HAWAII:
- chip_name = "HAWAII";
- pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
- me_req_size = CIK_ME_UCODE_SIZE * 4;
- ce_req_size = CIK_CE_UCODE_SIZE * 4;
- mec_req_size = CIK_MEC_UCODE_SIZE * 4;
- rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
- mc_req_size = HAWAII_MC_UCODE_SIZE * 4;
- sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
- smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4);
- break;
case CHIP_KAVERI:
chip_name = "KAVERI";
pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
@@ -1991,227 +1763,9 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev)
num_pipe_configs = rdev->config.cik.max_tile_pipes;
if (num_pipe_configs > 8)
- num_pipe_configs = 16;
+ num_pipe_configs = 8; /* ??? */
- if (num_pipe_configs == 16) {
- for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
- switch (reg_offset) {
- case 0:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
- break;
- case 1:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
- break;
- case 2:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
- break;
- case 3:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
- break;
- case 4:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- TILE_SPLIT(split_equal_to_row_size));
- break;
- case 5:
- gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
- break;
- case 6:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
- break;
- case 7:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- TILE_SPLIT(split_equal_to_row_size));
- break;
- case 8:
- gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16));
- break;
- case 9:
- gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
- break;
- case 10:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 11:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 12:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 13:
- gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
- break;
- case 14:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 16:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 17:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 27:
- gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
- break;
- case 28:
- gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 29:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- case 30:
- gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
- MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
- PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
- SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
- break;
- default:
- gb_tile_moden = 0;
- break;
- }
- rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
- WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
- }
- for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
- switch (reg_offset) {
- case 0:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
- NUM_BANKS(ADDR_SURF_16_BANK));
- break;
- case 1:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
- NUM_BANKS(ADDR_SURF_16_BANK));
- break;
- case 2:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_16_BANK));
- break;
- case 3:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_16_BANK));
- break;
- case 4:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_8_BANK));
- break;
- case 5:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_4_BANK));
- break;
- case 6:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_2_BANK));
- break;
- case 8:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
- NUM_BANKS(ADDR_SURF_16_BANK));
- break;
- case 9:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
- NUM_BANKS(ADDR_SURF_16_BANK));
- break;
- case 10:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_16_BANK));
- break;
- case 11:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_8_BANK));
- break;
- case 12:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_4_BANK));
- break;
- case 13:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_2_BANK));
- break;
- case 14:
- gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
- BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
- MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
- NUM_BANKS(ADDR_SURF_2_BANK));
- break;
- default:
- gb_tile_moden = 0;
- break;
- }
- WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
- }
- } else if (num_pipe_configs == 8) {
+ if (num_pipe_configs == 8) {
for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
switch (reg_offset) {
case 0:
@@ -2427,7 +1981,6 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev)
gb_tile_moden = 0;
break;
}
- rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
}
} else if (num_pipe_configs == 4) {
@@ -2774,7 +2327,6 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev)
gb_tile_moden = 0;
break;
}
- rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
}
} else if (num_pipe_configs == 2) {
@@ -2992,7 +2544,6 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev)
gb_tile_moden = 0;
break;
}
- rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
}
} else
@@ -3099,10 +2650,7 @@ static void cik_setup_rb(struct radeon_device *rdev,
for (j = 0; j < sh_per_se; j++) {
cik_select_se_sh(rdev, i, j);
data = cik_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se);
- if (rdev->family == CHIP_HAWAII)
- disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH);
- else
- disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH);
+ disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH);
}
}
cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
@@ -3119,12 +2667,6 @@ static void cik_setup_rb(struct radeon_device *rdev,
data = 0;
for (j = 0; j < sh_per_se; j++) {
switch (enabled_rbs & 3) {
- case 0:
- if (j == 0)
- data |= PKR_MAP(RASTER_CONFIG_RB_MAP_3);
- else
- data |= PKR_MAP(RASTER_CONFIG_RB_MAP_0);
- break;
case 1:
data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
break;
@@ -3177,23 +2719,6 @@ static void cik_gpu_init(struct radeon_device *rdev)
rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN;
break;
- case CHIP_HAWAII:
- rdev->config.cik.max_shader_engines = 4;
- rdev->config.cik.max_tile_pipes = 16;
- rdev->config.cik.max_cu_per_sh = 11;
- rdev->config.cik.max_sh_per_se = 1;
- rdev->config.cik.max_backends_per_se = 4;
- rdev->config.cik.max_texture_channel_caches = 16;
- rdev->config.cik.max_gprs = 256;
- rdev->config.cik.max_gs_threads = 32;
- rdev->config.cik.max_hw_contexts = 8;
-
- rdev->config.cik.sc_prim_fifo_size_frontend = 0x20;
- rdev->config.cik.sc_prim_fifo_size_backend = 0x100;
- rdev->config.cik.sc_hiz_tile_fifo_size = 0x30;
- rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
- gb_addr_config = HAWAII_GB_ADDR_CONFIG_GOLDEN;
- break;
case CHIP_KAVERI:
rdev->config.cik.max_shader_engines = 1;
rdev->config.cik.max_tile_pipes = 4;
@@ -3559,98 +3084,17 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, 0);
}
-bool cik_semaphore_ring_emit(struct radeon_device *rdev,
+void cik_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait)
{
-/* TODO: figure out why semaphore cause lockups */
-#if 0
uint64_t addr = semaphore->gpu_addr;
unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
radeon_ring_write(ring, addr & 0xffffffff);
radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel);
-
- return true;
-#else
- return false;
-#endif
-}
-
-/**
- * cik_copy_cpdma - copy pages using the CP DMA engine
- *
- * @rdev: radeon_device pointer
- * @src_offset: src GPU address
- * @dst_offset: dst GPU address
- * @num_gpu_pages: number of GPU pages to xfer
- * @fence: radeon fence object
- *
- * Copy GPU paging using the CP DMA engine (CIK+).
- * Used by the radeon ttm implementation to move pages if
- * registered as the asic copy callback.
- */
-int cik_copy_cpdma(struct radeon_device *rdev,
- uint64_t src_offset, uint64_t dst_offset,
- unsigned num_gpu_pages,
- struct radeon_fence **fence)
-{
- struct radeon_semaphore *sem = NULL;
- int ring_index = rdev->asic->copy.blit_ring_index;
- struct radeon_ring *ring = &rdev->ring[ring_index];
- u32 size_in_bytes, cur_size_in_bytes, control;
- int i, num_loops;
- int r = 0;
-
- r = radeon_semaphore_create(rdev, &sem);
- if (r) {
- DRM_ERROR("radeon: moving bo (%d).\n", r);
- return r;
- }
-
- size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
- num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
- r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18);
- if (r) {
- DRM_ERROR("radeon: moving bo (%d).\n", r);
- radeon_semaphore_free(rdev, &sem, NULL);
- return r;
- }
-
- radeon_semaphore_sync_to(sem, *fence);
- radeon_semaphore_sync_rings(rdev, sem, ring->idx);
-
- for (i = 0; i < num_loops; i++) {
- cur_size_in_bytes = size_in_bytes;
- if (cur_size_in_bytes > 0x1fffff)
- cur_size_in_bytes = 0x1fffff;
- size_in_bytes -= cur_size_in_bytes;
- control = 0;
- if (size_in_bytes == 0)
- control |= PACKET3_DMA_DATA_CP_SYNC;
- radeon_ring_write(ring, PACKET3(PACKET3_DMA_DATA, 5));
- radeon_ring_write(ring, control);
- radeon_ring_write(ring, lower_32_bits(src_offset));
- radeon_ring_write(ring, upper_32_bits(src_offset));
- radeon_ring_write(ring, lower_32_bits(dst_offset));
- radeon_ring_write(ring, upper_32_bits(dst_offset));
- radeon_ring_write(ring, cur_size_in_bytes);
- src_offset += cur_size_in_bytes;
- dst_offset += cur_size_in_bytes;
- }
-
- r = radeon_fence_emit(rdev, fence, ring->idx);
- if (r) {
- radeon_ring_unlock_undo(rdev, ring);
- return r;
- }
-
- radeon_ring_unlock_commit(rdev, ring);
- radeon_semaphore_free(rdev, &sem, *fence);
-
- return r;
}
/*
@@ -3959,8 +3403,7 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev)
int r;
WREG32(CP_SEM_WAIT_TIMER, 0x0);
- if (rdev->family != CHIP_HAWAII)
- WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
+ WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
/* Set the write pointer delay */
WREG32(CP_RB_WPTR_DELAY, 0);
@@ -4057,7 +3500,7 @@ void cik_compute_ring_set_wptr(struct radeon_device *rdev,
struct radeon_ring *ring)
{
rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(ring->wptr);
- WDOORBELL32(ring->doorbell_index, ring->wptr);
+ WDOORBELL32(ring->doorbell_offset, ring->wptr);
}
/**
@@ -4398,6 +3841,10 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
return r;
}
+ /* doorbell offset */
+ rdev->ring[idx].doorbell_offset =
+ (rdev->ring[idx].doorbell_page_num * PAGE_SIZE) + 0;
+
/* init the mqd struct */
memset(buf, 0, sizeof(struct bonaire_mqd));
@@ -4509,7 +3956,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
RREG32(CP_HQD_PQ_DOORBELL_CONTROL);
mqd->queue_state.cp_hqd_pq_doorbell_control &= ~DOORBELL_OFFSET_MASK;
mqd->queue_state.cp_hqd_pq_doorbell_control |=
- DOORBELL_OFFSET(rdev->ring[idx].doorbell_index);
+ DOORBELL_OFFSET(rdev->ring[idx].doorbell_offset / 4);
mqd->queue_state.cp_hqd_pq_doorbell_control |= DOORBELL_EN;
mqd->queue_state.cp_hqd_pq_doorbell_control &=
~(DOORBELL_SOURCE | DOORBELL_HIT);
@@ -5293,17 +4740,12 @@ void cik_vm_fini(struct radeon_device *rdev)
static void cik_vm_decode_fault(struct radeon_device *rdev,
u32 status, u32 addr, u32 mc_client)
{
- u32 mc_id;
+ u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
char block[5] = { mc_client >> 24, (mc_client >> 16) & 0xff,
(mc_client >> 8) & 0xff, mc_client & 0xff, 0 };
- if (rdev->family == CHIP_HAWAII)
- mc_id = (status & HAWAII_MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
- else
- mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
-
printk("VM fault (0x%02x, vmid %d) at page %u, %s from '%s' (0x%08x) (%d)\n",
protections, vmid, addr,
(status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
@@ -5392,6 +4834,62 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
}
}
+/**
+ * cik_vm_set_page - update the page tables using sDMA
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using CP or sDMA (CIK).
+ */
+void cik_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+ uint64_t value;
+ unsigned ndw;
+
+ if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
+ /* CP */
+ while (count) {
+ ndw = 2 + count * 2;
+ if (ndw > 0x3FFE)
+ ndw = 0x3FFE;
+
+ ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw);
+ ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(1));
+ ib->ptr[ib->length_dw++] = pe;
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+ for (; ndw > 2; ndw -= 2, --count, pe += 8) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
+ addr += incr;
+ value |= r600_flags;
+ ib->ptr[ib->length_dw++] = value;
+ ib->ptr[ib->length_dw++] = upper_32_bits(value);
+ }
+ }
+ } else {
+ /* DMA */
+ cik_sdma_vm_set_page(rdev, ib, pe, addr, count, incr, flags);
+ }
+}
+
/*
* RLC
* The RLC is a multi-purpose microengine that handles a
@@ -5560,7 +5058,6 @@ static int cik_rlc_resume(struct radeon_device *rdev)
switch (rdev->family) {
case CHIP_BONAIRE:
- case CHIP_HAWAII:
default:
size = BONAIRE_RLC_UCODE_SIZE;
break;
@@ -6059,7 +5556,7 @@ void cik_init_cp_pg_table(struct radeon_device *rdev)
}
for (i = 0; i < CP_ME_TABLE_SIZE; i ++) {
- dst_ptr[bo_offset + i] = cpu_to_le32(be32_to_cpu(fw_data[table_offset + i]));
+ dst_ptr[bo_offset + i] = be32_to_cpu(fw_data[table_offset + i]);
}
bo_offset += CP_ME_TABLE_SIZE;
}
@@ -6281,57 +5778,52 @@ void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
if (buffer == NULL)
return;
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
- buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
+ buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0);
+ buffer[count++] = PACKET3_PREAMBLE_BEGIN_CLEAR_STATE;
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
- buffer[count++] = cpu_to_le32(0x80000000);
- buffer[count++] = cpu_to_le32(0x80000000);
+ buffer[count++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1);
+ buffer[count++] = 0x80000000;
+ buffer[count++] = 0x80000000;
for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
for (ext = sect->section; ext->extent != NULL; ++ext) {
if (sect->id == SECT_CONTEXT) {
- buffer[count++] =
- cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
- buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);
+ buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count);
+ buffer[count++] = ext->reg_index - 0xa000;
for (i = 0; i < ext->reg_count; i++)
- buffer[count++] = cpu_to_le32(ext->extent[i]);
+ buffer[count++] = ext->extent[i];
} else {
return;
}
}
}
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 2));
- buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
+ buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2);
+ buffer[count++] = PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START;
switch (rdev->family) {
case CHIP_BONAIRE:
- buffer[count++] = cpu_to_le32(0x16000012);
- buffer[count++] = cpu_to_le32(0x00000000);
+ buffer[count++] = 0x16000012;
+ buffer[count++] = 0x00000000;
break;
case CHIP_KAVERI:
- buffer[count++] = cpu_to_le32(0x00000000); /* XXX */
- buffer[count++] = cpu_to_le32(0x00000000);
+ buffer[count++] = 0x00000000; /* XXX */
+ buffer[count++] = 0x00000000;
break;
case CHIP_KABINI:
- buffer[count++] = cpu_to_le32(0x00000000); /* XXX */
- buffer[count++] = cpu_to_le32(0x00000000);
- break;
- case CHIP_HAWAII:
- buffer[count++] = 0x3a00161a;
- buffer[count++] = 0x0000002e;
+ buffer[count++] = 0x00000000; /* XXX */
+ buffer[count++] = 0x00000000;
break;
default:
- buffer[count++] = cpu_to_le32(0x00000000);
- buffer[count++] = cpu_to_le32(0x00000000);
+ buffer[count++] = 0x00000000;
+ buffer[count++] = 0x00000000;
break;
}
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
- buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
+ buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0);
+ buffer[count++] = PACKET3_PREAMBLE_END_CLEAR_STATE;
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
- buffer[count++] = cpu_to_le32(0);
+ buffer[count++] = PACKET3(PACKET3_CLEAR_STATE, 0);
+ buffer[count++] = 0;
}
static void cik_init_pg(struct radeon_device *rdev)
@@ -7626,7 +7118,7 @@ static int cik_startup(struct radeon_device *rdev)
ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
CP_RB0_RPTR, CP_RB0_WPTR,
- PACKET3(PACKET3_NOP, 0x3FFF));
+ RADEON_CP_PACKET2);
if (r)
return r;
@@ -7840,14 +7332,14 @@ int cik_init(struct radeon_device *rdev)
ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
ring->ring_obj = NULL;
r600_ring_init(rdev, ring, 1024 * 1024);
- r = radeon_doorbell_get(rdev, &ring->doorbell_index);
+ r = radeon_doorbell_get(rdev, &ring->doorbell_page_num);
if (r)
return r;
ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
ring->ring_obj = NULL;
r600_ring_init(rdev, ring, 1024 * 1024);
- r = radeon_doorbell_get(rdev, &ring->doorbell_index);
+ r = radeon_doorbell_get(rdev, &ring->doorbell_page_num);
if (r)
return r;
@@ -7936,70 +7428,6 @@ void cik_fini(struct radeon_device *rdev)
rdev->bios = NULL;
}
-void dce8_program_fmt(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
- int bpc = 0;
- u32 tmp = 0;
- enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
-
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- bpc = radeon_get_monitor_bpc(connector);
- dither = radeon_connector->dither;
- }
-
- /* LVDS/eDP FMT is set up by atom */
- if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
- return;
-
- /* not needed for analog */
- if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ||
- (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2))
- return;
-
- if (bpc == 0)
- return;
-
- switch (bpc) {
- case 6:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
- FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(0));
- else
- tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(0));
- break;
- case 8:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
- FMT_RGB_RANDOM_ENABLE |
- FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(1));
- else
- tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(1));
- break;
- case 10:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
- FMT_RGB_RANDOM_ENABLE |
- FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(2));
- else
- tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(2));
- break;
- default:
- /* not needed */
- break;
- }
-
- WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp);
-}
-
/* display watermark setup */
/**
* dce8_line_buffer_adjust - Set up the line buffer
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index 0300727..b628606 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -25,7 +25,6 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_trace.h"
#include "cikd.h"
/* sdma */
@@ -102,6 +101,14 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
{
struct radeon_ring *ring = &rdev->ring[fence->ring];
u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
+ u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) |
+ SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */
+ u32 ref_and_mask;
+
+ if (fence->ring == R600_RING_TYPE_DMA_INDEX)
+ ref_and_mask = SDMA0;
+ else
+ ref_and_mask = SDMA1;
/* write the fence */
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_FENCE, 0, 0));
@@ -111,12 +118,12 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
/* generate an interrupt */
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0));
/* flush HDP */
- /* We should be using the new POLL_REG_MEM special op packet here
- * but it causes sDMA to hang sometimes
- */
- radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
- radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
- radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
+ radeon_ring_write(ring, GPU_HDP_FLUSH_DONE);
+ radeon_ring_write(ring, GPU_HDP_FLUSH_REQ);
+ radeon_ring_write(ring, ref_and_mask); /* REFERENCE */
+ radeon_ring_write(ring, ref_and_mask); /* MASK */
+ radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */
}
/**
@@ -130,7 +137,7 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
* Add a DMA semaphore packet to the ring wait on or signal
* other rings (CIK).
*/
-bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
+void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait)
@@ -141,8 +148,6 @@ bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SEMAPHORE, 0, extra_bits));
radeon_ring_write(ring, addr & 0xfffffff8);
radeon_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
-
- return true;
}
/**
@@ -445,8 +450,13 @@ int cik_copy_dma(struct radeon_device *rdev,
return r;
}
- radeon_semaphore_sync_to(sem, *fence);
- radeon_semaphore_sync_rings(rdev, sem, ring->idx);
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
for (i = 0; i < num_loops; i++) {
cur_size_in_bytes = size_in_bytes;
@@ -643,12 +653,11 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev,
uint64_t addr, unsigned count,
uint32_t incr, uint32_t flags)
{
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
uint64_t value;
unsigned ndw;
- trace_radeon_vm_set_page(pe, addr, count, incr, flags);
-
- if (flags & R600_PTE_SYSTEM) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
while (count) {
ndw = count * 2;
if (ndw > 0xFFFFE)
@@ -660,10 +669,16 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev,
ib->ptr[ib->length_dw++] = upper_32_bits(pe);
ib->ptr[ib->length_dw++] = ndw;
for (; ndw > 0; ndw -= 2, --count, pe += 8) {
- value = radeon_vm_map_gart(rdev, addr);
- value &= 0xFFFFFFFFFFFFF000ULL;
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
addr += incr;
- value |= flags;
+ value |= r600_flags;
ib->ptr[ib->length_dw++] = value;
ib->ptr[ib->length_dw++] = upper_32_bits(value);
}
@@ -674,7 +689,7 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev,
if (ndw > 0x7FFFF)
ndw = 0x7FFFF;
- if (flags & R600_PTE_VALID)
+ if (flags & RADEON_VM_PAGE_VALID)
value = addr;
else
value = 0;
@@ -682,7 +697,7 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev,
ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0);
ib->ptr[ib->length_dw++] = pe; /* dst addr */
ib->ptr[ib->length_dw++] = upper_32_bits(pe);
- ib->ptr[ib->length_dw++] = flags; /* mask */
+ ib->ptr[ib->length_dw++] = r600_flags; /* mask */
ib->ptr[ib->length_dw++] = 0;
ib->ptr[ib->length_dw++] = value; /* value */
ib->ptr[ib->length_dw++] = upper_32_bits(value);
@@ -709,10 +724,18 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev,
void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
{
struct radeon_ring *ring = &rdev->ring[ridx];
+ u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) |
+ SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */
+ u32 ref_and_mask;
if (vm == NULL)
return;
+ if (ridx == R600_RING_TYPE_DMA_INDEX)
+ ref_and_mask = SDMA0;
+ else
+ ref_and_mask = SDMA1;
+
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
if (vm->id < 8) {
radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2);
@@ -747,12 +770,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm
radeon_ring_write(ring, VMID(0));
/* flush HDP */
- /* We should be using the new POLL_REG_MEM special op packet here
- * but it causes sDMA to hang sometimes
- */
- radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
- radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
- radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
+ radeon_ring_write(ring, GPU_HDP_FLUSH_DONE);
+ radeon_ring_write(ring, GPU_HDP_FLUSH_REQ);
+ radeon_ring_write(ring, ref_and_mask); /* REFERENCE */
+ radeon_ring_write(ring, ref_and_mask); /* MASK */
+ radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */
/* flush TLB */
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index 5964af5..203d2a0 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -25,10 +25,8 @@
#define CIK_H
#define BONAIRE_GB_ADDR_CONFIG_GOLDEN 0x12010001
-#define HAWAII_GB_ADDR_CONFIG_GOLDEN 0x12011003
-#define CIK_RB_BITMAP_WIDTH_PER_SH 2
-#define HAWAII_RB_BITMAP_WIDTH_PER_SH 4
+#define CIK_RB_BITMAP_WIDTH_PER_SH 2
/* DIDT IND registers */
#define DIDT_SQ_CTRL0 0x0
@@ -501,7 +499,6 @@
* bit 4: write
*/
#define MEMORY_CLIENT_ID_MASK (0xff << 12)
-#define HAWAII_MEMORY_CLIENT_ID_MASK (0x1ff << 12)
#define MEMORY_CLIENT_ID_SHIFT 12
#define MEMORY_CLIENT_RW_MASK (1 << 24)
#define MEMORY_CLIENT_RW_SHIFT 24
@@ -909,39 +906,6 @@
#define DPG_PIPE_STUTTER_CONTROL 0x6cd4
# define STUTTER_ENABLE (1 << 0)
-/* DCE8 FMT blocks */
-#define FMT_DYNAMIC_EXP_CNTL 0x6fb4
-# define FMT_DYNAMIC_EXP_EN (1 << 0)
-# define FMT_DYNAMIC_EXP_MODE (1 << 4)
- /* 0 = 10bit -> 12bit, 1 = 8bit -> 12bit */
-#define FMT_CONTROL 0x6fb8
-# define FMT_PIXEL_ENCODING (1 << 16)
- /* 0 = RGB 4:4:4 or YCbCr 4:4:4, 1 = YCbCr 4:2:2 */
-#define FMT_BIT_DEPTH_CONTROL 0x6fc8
-# define FMT_TRUNCATE_EN (1 << 0)
-# define FMT_TRUNCATE_MODE (1 << 1)
-# define FMT_TRUNCATE_DEPTH(x) ((x) << 4) /* 0 - 18bpp, 1 - 24bpp, 2 - 30bpp */
-# define FMT_SPATIAL_DITHER_EN (1 << 8)
-# define FMT_SPATIAL_DITHER_MODE(x) ((x) << 9)
-# define FMT_SPATIAL_DITHER_DEPTH(x) ((x) << 11) /* 0 - 18bpp, 1 - 24bpp, 2 - 30bpp */
-# define FMT_FRAME_RANDOM_ENABLE (1 << 13)
-# define FMT_RGB_RANDOM_ENABLE (1 << 14)
-# define FMT_HIGHPASS_RANDOM_ENABLE (1 << 15)
-# define FMT_TEMPORAL_DITHER_EN (1 << 16)
-# define FMT_TEMPORAL_DITHER_DEPTH(x) ((x) << 17) /* 0 - 18bpp, 1 - 24bpp, 2 - 30bpp */
-# define FMT_TEMPORAL_DITHER_OFFSET(x) ((x) << 21)
-# define FMT_TEMPORAL_LEVEL (1 << 24)
-# define FMT_TEMPORAL_DITHER_RESET (1 << 25)
-# define FMT_25FRC_SEL(x) ((x) << 26)
-# define FMT_50FRC_SEL(x) ((x) << 28)
-# define FMT_75FRC_SEL(x) ((x) << 30)
-#define FMT_CLAMP_CONTROL 0x6fe4
-# define FMT_CLAMP_DATA_EN (1 << 0)
-# define FMT_CLAMP_COLOR_FORMAT(x) ((x) << 16)
-# define FMT_CLAMP_6BPC 0
-# define FMT_CLAMP_8BPC 1
-# define FMT_CLAMP_10BPC 2
-
#define GRBM_CNTL 0x8000
#define GRBM_READ_TIMEOUT(x) ((x) << 0)
@@ -1165,8 +1129,6 @@
# define ADDR_SURF_P8_32x32_16x16 12
# define ADDR_SURF_P8_32x32_16x32 13
# define ADDR_SURF_P8_32x64_32x32 14
-# define ADDR_SURF_P16_32x32_8x16 16
-# define ADDR_SURF_P16_32x32_16x16 17
# define TILE_SPLIT(x) ((x) << 11)
# define ADDR_SURF_TILE_SPLIT_64B 0
# define ADDR_SURF_TILE_SPLIT_128B 1
@@ -1460,7 +1422,6 @@
# define RASTER_CONFIG_RB_MAP_1 1
# define RASTER_CONFIG_RB_MAP_2 2
# define RASTER_CONFIG_RB_MAP_3 3
-#define PKR_MAP(x) ((x) << 8)
#define VGT_EVENT_INITIATOR 0x28a90
# define SAMPLE_STREAMOUTSTATS1 (1 << 0)
@@ -1753,68 +1714,6 @@
# define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28)
# define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28)
#define PACKET3_DMA_DATA 0x50
-/* 1. header
- * 2. CONTROL
- * 3. SRC_ADDR_LO or DATA [31:0]
- * 4. SRC_ADDR_HI [31:0]
- * 5. DST_ADDR_LO [31:0]
- * 6. DST_ADDR_HI [7:0]
- * 7. COMMAND [30:21] | BYTE_COUNT [20:0]
- */
-/* CONTROL */
-# define PACKET3_DMA_DATA_ENGINE(x) ((x) << 0)
- /* 0 - ME
- * 1 - PFP
- */
-# define PACKET3_DMA_DATA_SRC_CACHE_POLICY(x) ((x) << 13)
- /* 0 - LRU
- * 1 - Stream
- * 2 - Bypass
- */
-# define PACKET3_DMA_DATA_SRC_VOLATILE (1 << 15)
-# define PACKET3_DMA_DATA_DST_SEL(x) ((x) << 20)
- /* 0 - DST_ADDR using DAS
- * 1 - GDS
- * 3 - DST_ADDR using L2
- */
-# define PACKET3_DMA_DATA_DST_CACHE_POLICY(x) ((x) << 25)
- /* 0 - LRU
- * 1 - Stream
- * 2 - Bypass
- */
-# define PACKET3_DMA_DATA_DST_VOLATILE (1 << 27)
-# define PACKET3_DMA_DATA_SRC_SEL(x) ((x) << 29)
- /* 0 - SRC_ADDR using SAS
- * 1 - GDS
- * 2 - DATA
- * 3 - SRC_ADDR using L2
- */
-# define PACKET3_DMA_DATA_CP_SYNC (1 << 31)
-/* COMMAND */
-# define PACKET3_DMA_DATA_DIS_WC (1 << 21)
-# define PACKET3_DMA_DATA_CMD_SRC_SWAP(x) ((x) << 22)
- /* 0 - none
- * 1 - 8 in 16
- * 2 - 8 in 32
- * 3 - 8 in 64
- */
-# define PACKET3_DMA_DATA_CMD_DST_SWAP(x) ((x) << 24)
- /* 0 - none
- * 1 - 8 in 16
- * 2 - 8 in 32
- * 3 - 8 in 64
- */
-# define PACKET3_DMA_DATA_CMD_SAS (1 << 26)
- /* 0 - memory
- * 1 - register
- */
-# define PACKET3_DMA_DATA_CMD_DAS (1 << 27)
- /* 0 - memory
- * 1 - register
- */
-# define PACKET3_DMA_DATA_CMD_SAIC (1 << 28)
-# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
-# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
#define PACKET3_AQUIRE_MEM 0x58
#define PACKET3_REWIND 0x59
#define PACKET3_LOAD_UCONFIG_REG 0x5E
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
index 920e1e4..91bb470 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -299,9 +299,7 @@ void cypress_program_response_times(struct radeon_device *rdev)
static int cypress_pcie_performance_request(struct radeon_device *rdev,
u8 perf_req, bool advertise)
{
-#if defined(CONFIG_ACPI)
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
-#endif
u32 tmp;
udelay(10);
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c
index de86493..9fcd338 100644
--- a/drivers/gpu/drm/radeon/dce6_afmt.c
+++ b/drivers/gpu/drm/radeon/dce6_afmt.c
@@ -93,60 +93,15 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder)
struct radeon_device *rdev = encoder->dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- u32 offset;
+ u32 offset = dig->afmt->offset;
- if (!dig || !dig->afmt || !dig->afmt->pin)
+ if (!dig->afmt->pin)
return;
- offset = dig->afmt->offset;
-
WREG32(AFMT_AUDIO_SRC_CONTROL + offset,
AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id));
}
-void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
- struct drm_display_mode *mode)
-{
- struct radeon_device *rdev = encoder->dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
- u32 tmp = 0, offset;
-
- if (!dig || !dig->afmt || !dig->afmt->pin)
- return;
-
- offset = dig->afmt->pin->offset;
-
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
- if (connector->latency_present[1])
- tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
- AUDIO_LIPSYNC(connector->audio_latency[1]);
- else
- tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255);
- } else {
- if (connector->latency_present[0])
- tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
- AUDIO_LIPSYNC(connector->audio_latency[0]);
- else
- tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255);
- }
- WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
-}
-
void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
{
struct radeon_device *rdev = encoder->dev->dev_private;
@@ -158,7 +113,10 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
u8 *sadb;
int sad_count;
- if (!dig || !dig->afmt || !dig->afmt->pin)
+ /* XXX: setting this register causes hangs on some asics */
+ return;
+
+ if (!dig->afmt->pin)
return;
offset = dig->afmt->pin->offset;
@@ -219,7 +177,7 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
};
- if (!dig || !dig->afmt || !dig->afmt->pin)
+ if (!dig->afmt->pin)
return;
offset = dig->afmt->pin->offset;
@@ -243,30 +201,20 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
u32 value = 0;
- u8 stereo_freqs = 0;
- int max_channels = -1;
int j;
for (j = 0; j < sad_count; j++) {
struct cea_sad *sad = &sads[j];
if (sad->format == eld_reg_to_type[i][1]) {
- if (sad->channels > max_channels) {
- value = MAX_CHANNELS(sad->channels) |
- DESCRIPTOR_BYTE_2(sad->byte2) |
- SUPPORTED_FREQUENCIES(sad->freq);
- max_channels = sad->channels;
- }
-
+ value = MAX_CHANNELS(sad->channels) |
+ DESCRIPTOR_BYTE_2(sad->byte2) |
+ SUPPORTED_FREQUENCIES(sad->freq);
if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
- stereo_freqs |= sad->freq;
- else
- break;
+ value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq);
+ break;
}
}
-
- value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
-
WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value);
}
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 9702e55..b5c67a9 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1174,72 +1174,23 @@ int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
{
- int readrq;
- u16 v;
+ u16 ctl, v;
+ int err;
- readrq = pcie_get_readrq(rdev->pdev);
- v = ffs(readrq) - 8;
- /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it
- * to avoid hangs or perfomance issues
- */
- if ((v == 0) || (v == 6) || (v == 7))
- pcie_set_readrq(rdev->pdev, 512);
-}
-
-void dce4_program_fmt(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
- int bpc = 0;
- u32 tmp = 0;
- enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
-
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- bpc = radeon_get_monitor_bpc(connector);
- dither = radeon_connector->dither;
- }
-
- /* LVDS/eDP FMT is set up by atom */
- if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
+ err = pcie_capability_read_word(rdev->pdev, PCI_EXP_DEVCTL, &ctl);
+ if (err)
return;
- /* not needed for analog */
- if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ||
- (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2))
- return;
-
- if (bpc == 0)
- return;
+ v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12;
- switch (bpc) {
- case 6:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
- FMT_SPATIAL_DITHER_EN);
- else
- tmp |= FMT_TRUNCATE_EN;
- break;
- case 8:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
- FMT_RGB_RANDOM_ENABLE |
- FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH);
- else
- tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH);
- break;
- case 10:
- default:
- /* not needed */
- break;
+ /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it
+ * to avoid hangs or perfomance issues
+ */
+ if ((v == 0) || (v == 6) || (v == 7)) {
+ ctl &= ~PCI_EXP_DEVCTL_READRQ;
+ ctl |= (2 << 12);
+ pcie_capability_write_word(rdev->pdev, PCI_EXP_DEVCTL, ctl);
}
-
- WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp);
}
static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc)
@@ -4012,7 +3963,7 @@ int sumo_rlc_init(struct radeon_device *rdev)
if (rdev->family >= CHIP_TAHITI) {
/* SI */
for (i = 0; i < rdev->rlc.reg_list_size; i++)
- dst_ptr[i] = cpu_to_le32(src_ptr[i]);
+ dst_ptr[i] = src_ptr[i];
} else {
/* ON/LN/TN */
/* format:
@@ -4026,10 +3977,10 @@ int sumo_rlc_init(struct radeon_device *rdev)
if (i < dws)
data |= (src_ptr[i] >> 2) << 16;
j = (((i - 1) * 3) / 2);
- dst_ptr[j] = cpu_to_le32(data);
+ dst_ptr[j] = data;
}
j = ((i * 3) / 2);
- dst_ptr[j] = cpu_to_le32(RLC_SAVE_RESTORE_LIST_END_MARKER);
+ dst_ptr[j] = RLC_SAVE_RESTORE_LIST_END_MARKER;
}
radeon_bo_kunmap(rdev->rlc.save_restore_obj);
radeon_bo_unreserve(rdev->rlc.save_restore_obj);
@@ -4091,40 +4042,40 @@ int sumo_rlc_init(struct radeon_device *rdev)
cik_get_csb_buffer(rdev, dst_ptr);
} else if (rdev->family >= CHIP_TAHITI) {
reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + 256;
- dst_ptr[0] = cpu_to_le32(upper_32_bits(reg_list_mc_addr));
- dst_ptr[1] = cpu_to_le32(lower_32_bits(reg_list_mc_addr));
- dst_ptr[2] = cpu_to_le32(rdev->rlc.clear_state_size);
+ dst_ptr[0] = upper_32_bits(reg_list_mc_addr);
+ dst_ptr[1] = lower_32_bits(reg_list_mc_addr);
+ dst_ptr[2] = rdev->rlc.clear_state_size;
si_get_csb_buffer(rdev, &dst_ptr[(256/4)]);
} else {
reg_list_hdr_blk_index = 0;
reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
data = upper_32_bits(reg_list_mc_addr);
- dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
+ dst_ptr[reg_list_hdr_blk_index] = data;
reg_list_hdr_blk_index++;
for (i = 0; cs_data[i].section != NULL; i++) {
for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
reg_num = cs_data[i].section[j].reg_count;
data = reg_list_mc_addr & 0xffffffff;
- dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
+ dst_ptr[reg_list_hdr_blk_index] = data;
reg_list_hdr_blk_index++;
data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
- dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
+ dst_ptr[reg_list_hdr_blk_index] = data;
reg_list_hdr_blk_index++;
data = 0x08000000 | (reg_num * 4);
- dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
+ dst_ptr[reg_list_hdr_blk_index] = data;
reg_list_hdr_blk_index++;
for (k = 0; k < reg_num; k++) {
data = cs_data[i].section[j].extent[k];
- dst_ptr[reg_list_blk_index + k] = cpu_to_le32(data);
+ dst_ptr[reg_list_blk_index + k] = data;
}
reg_list_mc_addr += reg_num * 4;
reg_list_blk_index += reg_num;
}
}
- dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(RLC_CLEAR_STATE_END_MARKER);
+ dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER;
}
radeon_bo_kunmap(rdev->rlc.clear_state_obj);
radeon_bo_unreserve(rdev->rlc.clear_state_obj);
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c
index a37b544..6a0656d 100644
--- a/drivers/gpu/drm/radeon/evergreen_dma.c
+++ b/drivers/gpu/drm/radeon/evergreen_dma.c
@@ -131,8 +131,13 @@ int evergreen_copy_dma(struct radeon_device *rdev,
return r;
}
- radeon_semaphore_sync_to(sem, *fence);
- radeon_semaphore_sync_rings(rdev, sem, ring->idx);
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
for (i = 0; i < num_loops; i++) {
cur_size_in_dw = size_in_dw;
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index aa695c4..57fcc4b 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -35,8 +35,6 @@
extern void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder);
extern void dce6_afmt_write_sad_regs(struct drm_encoder *encoder);
extern void dce6_afmt_select_pin(struct drm_encoder *encoder);
-extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
- struct drm_display_mode *mode);
/*
* update the N and CTS parameters for a given pixel clock rate
@@ -60,42 +58,6 @@ static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t cloc
WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz);
}
-static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder,
- struct drm_display_mode *mode)
-{
- struct radeon_device *rdev = encoder->dev->dev_private;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
- u32 tmp = 0;
-
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
- if (connector->latency_present[1])
- tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
- AUDIO_LIPSYNC(connector->audio_latency[1]);
- else
- tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255);
- } else {
- if (connector->latency_present[0])
- tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
- AUDIO_LIPSYNC(connector->audio_latency[0]);
- else
- tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255);
- }
- WREG32(AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp);
-}
-
static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
{
struct radeon_device *rdev = encoder->dev->dev_private;
@@ -105,11 +67,12 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
u8 *sadb;
int sad_count;
+ /* XXX: setting this register causes hangs on some asics */
+ return;
+
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
+ if (connector->encoder == encoder)
radeon_connector = to_radeon_connector(connector);
- break;
- }
}
if (!radeon_connector) {
@@ -161,10 +124,8 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
};
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
+ if (connector->encoder == encoder)
radeon_connector = to_radeon_connector(connector);
- break;
- }
}
if (!radeon_connector) {
@@ -181,30 +142,20 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
u32 value = 0;
- u8 stereo_freqs = 0;
- int max_channels = -1;
int j;
for (j = 0; j < sad_count; j++) {
struct cea_sad *sad = &sads[j];
if (sad->format == eld_reg_to_type[i][1]) {
- if (sad->channels > max_channels) {
- value = MAX_CHANNELS(sad->channels) |
- DESCRIPTOR_BYTE_2(sad->byte2) |
- SUPPORTED_FREQUENCIES(sad->freq);
- max_channels = sad->channels;
- }
-
+ value = MAX_CHANNELS(sad->channels) |
+ DESCRIPTOR_BYTE_2(sad->byte2) |
+ SUPPORTED_FREQUENCIES(sad->freq);
if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
- stereo_freqs |= sad->freq;
- else
- break;
+ value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq);
+ break;
}
}
-
- value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
-
WREG32(eld_reg_to_type[i][0], value);
}
@@ -373,10 +324,8 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
if (ASIC_IS_DCE6(rdev)) {
dce6_afmt_select_pin(encoder);
dce6_afmt_write_sad_regs(encoder);
- dce6_afmt_write_latency_fields(encoder, mode);
} else {
evergreen_hdmi_write_sad_regs(encoder);
- dce4_afmt_write_latency_fields(encoder, mode);
}
err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 17f9907..4f6d296 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -750,44 +750,6 @@
* bit6 = 192 kHz
*/
-#define AZ_CHANNEL_COUNT_CONTROL 0x5fe4
-# define HBR_CHANNEL_COUNT(x) (((x) & 0x7) << 0)
-# define COMPRESSED_CHANNEL_COUNT(x) (((x) & 0x7) << 4)
-/* HBR_CHANNEL_COUNT, COMPRESSED_CHANNEL_COUNT
- * 0 = use stream header
- * 1-7 = channel count - 1
- */
-#define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC 0x5fe8
-# define VIDEO_LIPSYNC(x) (((x) & 0xff) << 0)
-# define AUDIO_LIPSYNC(x) (((x) & 0xff) << 8)
-/* VIDEO_LIPSYNC, AUDIO_LIPSYNC
- * 0 = invalid
- * x = legal delay value
- * 255 = sync not supported
- */
-#define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_HBR 0x5fec
-# define HBR_CAPABLE (1 << 0) /* enabled by default */
-
-#define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_AV_ASSOCIATION0 0x5ff4
-# define DISPLAY0_TYPE(x) (((x) & 0x3) << 0)
-# define DISPLAY_TYPE_NONE 0
-# define DISPLAY_TYPE_HDMI 1
-# define DISPLAY_TYPE_DP 2
-# define DISPLAY0_ID(x) (((x) & 0x3f) << 2)
-# define DISPLAY1_TYPE(x) (((x) & 0x3) << 8)
-# define DISPLAY1_ID(x) (((x) & 0x3f) << 10)
-# define DISPLAY2_TYPE(x) (((x) & 0x3) << 16)
-# define DISPLAY2_ID(x) (((x) & 0x3f) << 18)
-# define DISPLAY3_TYPE(x) (((x) & 0x3) << 24)
-# define DISPLAY3_ID(x) (((x) & 0x3f) << 26)
-#define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_AV_ASSOCIATION1 0x5ff8
-# define DISPLAY4_TYPE(x) (((x) & 0x3) << 0)
-# define DISPLAY4_ID(x) (((x) & 0x3f) << 2)
-# define DISPLAY5_TYPE(x) (((x) & 0x3) << 8)
-# define DISPLAY5_ID(x) (((x) & 0x3f) << 10)
-#define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_AV_NUMBER 0x5ffc
-# define NUMBER_OF_DISPLAY_ID(x) (((x) & 0x7) << 0)
-
#define AZ_HOT_PLUG_CONTROL 0x5e78
# define AZ_FORCE_CODEC_WAKE (1 << 0)
# define PIN0_JACK_DETECTION_ENABLE (1 << 4)
@@ -1350,38 +1312,6 @@
# define DC_HPDx_RX_INT_TIMER(x) ((x) << 16)
# define DC_HPDx_EN (1 << 28)
-/* DCE4/5/6 FMT blocks */
-#define FMT_DYNAMIC_EXP_CNTL 0x6fb4
-# define FMT_DYNAMIC_EXP_EN (1 << 0)
-# define FMT_DYNAMIC_EXP_MODE (1 << 4)
- /* 0 = 10bit -> 12bit, 1 = 8bit -> 12bit */
-#define FMT_CONTROL 0x6fb8
-# define FMT_PIXEL_ENCODING (1 << 16)
- /* 0 = RGB 4:4:4 or YCbCr 4:4:4, 1 = YCbCr 4:2:2 */
-#define FMT_BIT_DEPTH_CONTROL 0x6fc8
-# define FMT_TRUNCATE_EN (1 << 0)
-# define FMT_TRUNCATE_DEPTH (1 << 4)
-# define FMT_SPATIAL_DITHER_EN (1 << 8)
-# define FMT_SPATIAL_DITHER_MODE(x) ((x) << 9)
-# define FMT_SPATIAL_DITHER_DEPTH (1 << 12)
-# define FMT_FRAME_RANDOM_ENABLE (1 << 13)
-# define FMT_RGB_RANDOM_ENABLE (1 << 14)
-# define FMT_HIGHPASS_RANDOM_ENABLE (1 << 15)
-# define FMT_TEMPORAL_DITHER_EN (1 << 16)
-# define FMT_TEMPORAL_DITHER_DEPTH (1 << 20)
-# define FMT_TEMPORAL_DITHER_OFFSET(x) ((x) << 21)
-# define FMT_TEMPORAL_LEVEL (1 << 24)
-# define FMT_TEMPORAL_DITHER_RESET (1 << 25)
-# define FMT_25FRC_SEL(x) ((x) << 26)
-# define FMT_50FRC_SEL(x) ((x) << 28)
-# define FMT_75FRC_SEL(x) ((x) << 30)
-#define FMT_CLAMP_CONTROL 0x6fe4
-# define FMT_CLAMP_DATA_EN (1 << 0)
-# define FMT_CLAMP_COLOR_FORMAT(x) ((x) << 16)
-# define FMT_CLAMP_6BPC 0
-# define FMT_CLAMP_8BPC 1
-# define FMT_CLAMP_10BPC 2
-
/* ASYNC DMA */
#define DMA_RB_RPTR 0xd008
#define DMA_RB_WPTR 0xd00c
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 11aab2a..cac2866 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -174,6 +174,11 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
extern void evergreen_program_aspm(struct radeon_device *rdev);
extern void sumo_rlc_fini(struct radeon_device *rdev);
extern int sumo_rlc_init(struct radeon_device *rdev);
+extern void cayman_dma_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
/* Firmware Names */
MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
@@ -2395,6 +2400,77 @@ void cayman_vm_decode_fault(struct radeon_device *rdev,
block, mc_id);
}
+#define R600_ENTRY_VALID (1 << 0)
+#define R600_PTE_SYSTEM (1 << 1)
+#define R600_PTE_SNOOPED (1 << 2)
+#define R600_PTE_READABLE (1 << 5)
+#define R600_PTE_WRITEABLE (1 << 6)
+
+uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags)
+{
+ uint32_t r600_flags = 0;
+ r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0;
+ r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0;
+ r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0;
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ r600_flags |= R600_PTE_SYSTEM;
+ r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0;
+ }
+ return r600_flags;
+}
+
+/**
+ * cayman_vm_set_page - update the page tables using the CP
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using the CP (cayman/TN).
+ */
+void cayman_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+ uint64_t value;
+ unsigned ndw;
+
+ if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
+ while (count) {
+ ndw = 1 + count * 2;
+ if (ndw > 0x3FFF)
+ ndw = 0x3FFF;
+
+ ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw);
+ ib->ptr[ib->length_dw++] = pe;
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
+ for (; ndw > 1; ndw -= 2, --count, pe += 8) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
+ addr += incr;
+ value |= r600_flags;
+ ib->ptr[ib->length_dw++] = value;
+ ib->ptr[ib->length_dw++] = upper_32_bits(value);
+ }
+ }
+ } else {
+ cayman_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags);
+ }
+}
+
/**
* cayman_vm_flush - vm flush using the CP
*
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c
index bdeb65e..dd6e968 100644
--- a/drivers/gpu/drm/radeon/ni_dma.c
+++ b/drivers/gpu/drm/radeon/ni_dma.c
@@ -24,7 +24,6 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_trace.h"
#include "nid.h"
u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev);
@@ -246,7 +245,8 @@ bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
* @addr: dst addr to write into pe
* @count: number of page entries to update
* @incr: increase next addr by incr bytes
- * @flags: hw access flags
+ * @flags: access flags
+ * @r600_flags: hw access flags
*
* Update the page tables using the DMA (cayman/TN).
*/
@@ -256,12 +256,11 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev,
uint64_t addr, unsigned count,
uint32_t incr, uint32_t flags)
{
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
uint64_t value;
unsigned ndw;
- trace_radeon_vm_set_page(pe, addr, count, incr, flags);
-
- if ((flags & R600_PTE_SYSTEM) || (count == 1)) {
+ if ((flags & RADEON_VM_PAGE_SYSTEM) || (count == 1)) {
while (count) {
ndw = count * 2;
if (ndw > 0xFFFFE)
@@ -272,16 +271,16 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev,
ib->ptr[ib->length_dw++] = pe;
ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
for (; ndw > 0; ndw -= 2, --count, pe += 8) {
- if (flags & R600_PTE_SYSTEM) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
value = radeon_vm_map_gart(rdev, addr);
value &= 0xFFFFFFFFFFFFF000ULL;
- } else if (flags & R600_PTE_VALID) {
+ } else if (flags & RADEON_VM_PAGE_VALID) {
value = addr;
} else {
value = 0;
}
addr += incr;
- value |= flags;
+ value |= r600_flags;
ib->ptr[ib->length_dw++] = value;
ib->ptr[ib->length_dw++] = upper_32_bits(value);
}
@@ -292,7 +291,7 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev,
if (ndw > 0xFFFFE)
ndw = 0xFFFFE;
- if (flags & R600_PTE_VALID)
+ if (flags & RADEON_VM_PAGE_VALID)
value = addr;
else
value = 0;
@@ -300,7 +299,7 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev,
ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
ib->ptr[ib->length_dw++] = pe; /* dst addr */
ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
- ib->ptr[ib->length_dw++] = flags; /* mask */
+ ib->ptr[ib->length_dw++] = r600_flags; /* mask */
ib->ptr[ib->length_dw++] = 0;
ib->ptr[ib->length_dw++] = value; /* value */
ib->ptr[ib->length_dw++] = upper_32_bits(value);
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 49c4d48..f263390 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -785,8 +785,8 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
struct ni_ps *ps = ni_get_ps(rps);
struct radeon_clock_and_voltage_limits *max_limits;
bool disable_mclk_switching;
- u32 mclk;
- u16 vddci;
+ u32 mclk, sclk;
+ u16 vddc, vddci;
u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
int i;
@@ -839,14 +839,24 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
/* XXX validate the min clocks required for display */
- /* adjust low state */
if (disable_mclk_switching) {
- ps->performance_levels[0].mclk =
- ps->performance_levels[ps->performance_level_count - 1].mclk;
- ps->performance_levels[0].vddci =
- ps->performance_levels[ps->performance_level_count - 1].vddci;
+ mclk = ps->performance_levels[ps->performance_level_count - 1].mclk;
+ sclk = ps->performance_levels[0].sclk;
+ vddc = ps->performance_levels[0].vddc;
+ vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
+ } else {
+ sclk = ps->performance_levels[0].sclk;
+ mclk = ps->performance_levels[0].mclk;
+ vddc = ps->performance_levels[0].vddc;
+ vddci = ps->performance_levels[0].vddci;
}
+ /* adjusted low state */
+ ps->performance_levels[0].sclk = sclk;
+ ps->performance_levels[0].mclk = mclk;
+ ps->performance_levels[0].vddc = vddc;
+ ps->performance_levels[0].vddci = vddci;
+
btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
&ps->performance_levels[0].sclk,
&ps->performance_levels[0].mclk);
@@ -858,15 +868,11 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
}
- /* adjust remaining states */
if (disable_mclk_switching) {
mclk = ps->performance_levels[0].mclk;
- vddci = ps->performance_levels[0].vddci;
for (i = 1; i < ps->performance_level_count; i++) {
if (mclk < ps->performance_levels[i].mclk)
mclk = ps->performance_levels[i].mclk;
- if (vddci < ps->performance_levels[i].vddci)
- vddci = ps->performance_levels[i].vddci;
}
for (i = 0; i < ps->performance_level_count; i++) {
ps->performance_levels[i].mclk = mclk;
@@ -3439,9 +3445,9 @@ static int ni_enable_smc_cac(struct radeon_device *rdev,
static int ni_pcie_performance_request(struct radeon_device *rdev,
u8 perf_req, bool advertise)
{
-#if defined(CONFIG_ACPI)
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+#if defined(CONFIG_ACPI)
if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) ||
(perf_req == PCIE_PERF_REQ_PECI_GEN2)) {
if (eg_pi->pcie_performance_request_registered == false)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 10abc4d..d713330 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -869,14 +869,13 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, RADEON_SW_INT_FIRE);
}
-bool r100_semaphore_ring_emit(struct radeon_device *rdev,
+void r100_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait)
{
/* Unused on older asics, since we don't have semaphores or multiple rings */
BUG();
- return false;
}
int r100_copy_blit(struct radeon_device *rdev,
@@ -1435,7 +1434,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
- return -ENOENT;
+ return -EINVAL;
}
crtc = obj_to_crtc(obj);
radeon_crtc = to_radeon_crtc(crtc);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 9ad0673..f9be220 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -124,59 +124,6 @@ int r600_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
return 0;
}
-void dce3_program_fmt(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
- int bpc = 0;
- u32 tmp = 0;
- enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
-
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- bpc = radeon_get_monitor_bpc(connector);
- dither = radeon_connector->dither;
- }
-
- /* LVDS FMT is set up by atom */
- if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
- return;
-
- /* not needed for analog */
- if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ||
- (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2))
- return;
-
- if (bpc == 0)
- return;
-
- switch (bpc) {
- case 6:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= FMT_SPATIAL_DITHER_EN;
- else
- tmp |= FMT_TRUNCATE_EN;
- break;
- case 8:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= (FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH);
- else
- tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH);
- break;
- case 10:
- default:
- /* not needed */
- break;
- }
-
- WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp);
-}
-
/* get temperature in millidegrees */
int rv6xx_get_temp(struct radeon_device *rdev)
{
@@ -2650,7 +2597,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
}
}
-bool r600_semaphore_ring_emit(struct radeon_device *rdev,
+void r600_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait)
@@ -2664,8 +2611,6 @@ bool r600_semaphore_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
radeon_ring_write(ring, addr & 0xffffffff);
radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel);
-
- return true;
}
/**
@@ -2708,8 +2653,13 @@ int r600_copy_cpdma(struct radeon_device *rdev,
return r;
}
- radeon_semaphore_sync_to(sem, *fence);
- radeon_semaphore_sync_rings(rdev, sem, ring->idx);
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 5dceea6..01a3ec8 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -887,7 +887,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
- return -ENOENT;
+ return -EINVAL;
}
crtc = obj_to_crtc(obj);
radeon_crtc = to_radeon_crtc(crtc);
@@ -2328,8 +2328,13 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error)
unsigned i;
kfree(parser->relocs);
- for (i = 0; i < parser->nchunks; i++)
- drm_free_large(parser->chunks[i].kdata);
+ for (i = 0; i < parser->nchunks; i++) {
+ kfree(parser->chunks[i].kdata);
+ if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) {
+ kfree(parser->chunks[i].kpage[0]);
+ kfree(parser->chunks[i].kpage[1]);
+ }
+ }
kfree(parser->chunks);
kfree(parser->chunks_array);
}
@@ -2386,12 +2391,13 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
ib_chunk = &parser.chunks[parser.chunk_ib_idx];
parser.ib.length_dw = ib_chunk->length_dw;
*l = parser.ib.length_dw;
- if (DRM_COPY_FROM_USER(ib, ib_chunk->user_ptr, ib_chunk->length_dw * 4)) {
- r = -EFAULT;
+ r = r600_cs_parse(&parser);
+ if (r) {
+ DRM_ERROR("Invalid command stream !\n");
r600_cs_parser_fini(&parser, r);
return r;
}
- r = r600_cs_parse(&parser);
+ r = radeon_cs_finish_pages(&parser);
if (r) {
DRM_ERROR("Invalid command stream !\n");
r600_cs_parser_fini(&parser, r);
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c
index 7844d15..3b31745 100644
--- a/drivers/gpu/drm/radeon/r600_dma.c
+++ b/drivers/gpu/drm/radeon/r600_dma.c
@@ -311,7 +311,7 @@ void r600_dma_fence_ring_emit(struct radeon_device *rdev,
* Add a DMA semaphore packet to the ring wait on or signal
* other rings (r6xx-SI).
*/
-bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
+void r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait)
@@ -322,8 +322,6 @@ bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SEMAPHORE, 0, s, 0));
radeon_ring_write(ring, addr & 0xfffffffc);
radeon_ring_write(ring, upper_32_bits(addr) & 0xff);
-
- return true;
}
/**
@@ -464,8 +462,13 @@ int r600_copy_dma(struct radeon_device *rdev,
return r;
}
- radeon_semaphore_sync_to(sem, *fence);
- radeon_semaphore_sync_rings(rdev, sem, ring->idx);
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
for (i = 0; i < num_loops; i++) {
cur_size_in_dw = size_in_dw;
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index b7d3ecb..06022e3 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -24,7 +24,6 @@
* Authors: Christian König
*/
#include <linux/hdmi.h>
-#include <linux/gcd.h>
#include <drm/drmP.h>
#include <drm/radeon_drm.h>
#include "radeon.h"
@@ -58,57 +57,35 @@ enum r600_hdmi_iec_status_bits {
static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
/* 32kHz 44.1kHz 48kHz */
/* Clock N CTS N CTS N CTS */
- { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
+ { 25175, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */
{ 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
{ 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
{ 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
{ 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
{ 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
- { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
+ { 74176, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */
{ 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
- { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
+ { 148352, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */
{ 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
+ { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */
};
-
/*
- * calculate CTS and N values if they are not found in the table
+ * calculate CTS value if it's not found in the table
*/
-static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq)
+static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq)
{
- int n, cts;
- unsigned long div, mul;
-
- /* Safe, but overly large values */
- n = 128 * freq;
- cts = clock * 1000;
-
- /* Smallest valid fraction */
- div = gcd(n, cts);
-
- n /= div;
- cts /= div;
-
- /*
- * The optimal N is 128*freq/1000. Calculate the closest larger
- * value that doesn't truncate any bits.
- */
- mul = ((128*freq/1000) + (n-1))/n;
-
- n *= mul;
- cts *= mul;
-
- /* Check that we are in spec (not always possible) */
- if (n < (128*freq/1500))
- printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
- if (n > (128*freq/300))
- printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
-
- *N = n;
- *CTS = cts;
-
- DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
- *N, *CTS, freq);
+ u64 n;
+ u32 d;
+
+ if (*CTS == 0) {
+ n = (u64)clock * (u64)N * 1000ULL;
+ d = 128 * freq;
+ do_div(n, d);
+ *CTS = n;
+ }
+ DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
+ N, *CTS, freq);
}
struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
@@ -116,16 +93,15 @@ struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
struct radeon_hdmi_acr res;
u8 i;
- /* Precalculated values for common clocks */
- for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) {
- if (r600_hdmi_predefined_acr[i].clock == clock)
- return r600_hdmi_predefined_acr[i];
- }
+ for (i = 0; r600_hdmi_predefined_acr[i].clock != clock &&
+ r600_hdmi_predefined_acr[i].clock != 0; i++)
+ ;
+ res = r600_hdmi_predefined_acr[i];
- /* And odd clocks get manually calculated */
- r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
- r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
- r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
+ /* In case some CTS are missing */
+ r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000);
+ r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100);
+ r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000);
return res;
}
@@ -304,9 +280,9 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo);
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
}
- } else {
+ } else if (ASIC_IS_DCE3(rdev)) {
/* according to the reg specs, this should DCE3.2 only, but in
- * practice it seems to cover DCE2.0/3.0/3.1 as well.
+ * practice it seems to cover DCE3.0/3.1 as well.
*/
if (dig->dig_encoder == 0) {
WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
@@ -317,6 +293,10 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
}
+ } else {
+ /* according to the reg specs, this should be DCE2.0 and DCE3.0/3.1 */
+ WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
+ AUDIO_DTO_MODULE(clock / 10));
}
}
@@ -333,10 +313,8 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder)
return;
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
+ if (connector->encoder == encoder)
radeon_connector = to_radeon_connector(connector);
- break;
- }
}
if (!radeon_connector) {
@@ -388,10 +366,8 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)
};
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
+ if (connector->encoder == encoder)
radeon_connector = to_radeon_connector(connector);
- break;
- }
}
if (!radeon_connector) {
@@ -408,30 +384,20 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)
for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
u32 value = 0;
- u8 stereo_freqs = 0;
- int max_channels = -1;
int j;
for (j = 0; j < sad_count; j++) {
struct cea_sad *sad = &sads[j];
if (sad->format == eld_reg_to_type[i][1]) {
- if (sad->channels > max_channels) {
- value = MAX_CHANNELS(sad->channels) |
- DESCRIPTOR_BYTE_2(sad->byte2) |
- SUPPORTED_FREQUENCIES(sad->freq);
- max_channels = sad->channels;
- }
-
+ value = MAX_CHANNELS(sad->channels) |
+ DESCRIPTOR_BYTE_2(sad->byte2) |
+ SUPPORTED_FREQUENCIES(sad->freq);
if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
- stereo_freqs |= sad->freq;
- else
- break;
+ value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq);
+ break;
}
}
-
- value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
-
WREG32(eld_reg_to_type[i][0], value);
}
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index ebe3872..7b3c7b5 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -1199,34 +1199,6 @@
# define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29)
# define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30)
-/* DCE3 FMT blocks */
-#define FMT_CONTROL 0x6700
-# define FMT_PIXEL_ENCODING (1 << 16)
- /* 0 = RGB 4:4:4 or YCbCr 4:4:4, 1 = YCbCr 4:2:2 */
-#define FMT_BIT_DEPTH_CONTROL 0x6710
-# define FMT_TRUNCATE_EN (1 << 0)
-# define FMT_TRUNCATE_DEPTH (1 << 4)
-# define FMT_SPATIAL_DITHER_EN (1 << 8)
-# define FMT_SPATIAL_DITHER_MODE(x) ((x) << 9)
-# define FMT_SPATIAL_DITHER_DEPTH (1 << 12)
-# define FMT_FRAME_RANDOM_ENABLE (1 << 13)
-# define FMT_RGB_RANDOM_ENABLE (1 << 14)
-# define FMT_HIGHPASS_RANDOM_ENABLE (1 << 15)
-# define FMT_TEMPORAL_DITHER_EN (1 << 16)
-# define FMT_TEMPORAL_DITHER_DEPTH (1 << 20)
-# define FMT_TEMPORAL_DITHER_OFFSET(x) ((x) << 21)
-# define FMT_TEMPORAL_LEVEL (1 << 24)
-# define FMT_TEMPORAL_DITHER_RESET (1 << 25)
-# define FMT_25FRC_SEL(x) ((x) << 26)
-# define FMT_50FRC_SEL(x) ((x) << 28)
-# define FMT_75FRC_SEL(x) ((x) << 30)
-#define FMT_CLAMP_CONTROL 0x672c
-# define FMT_CLAMP_DATA_EN (1 << 0)
-# define FMT_CLAMP_COLOR_FORMAT(x) ((x) << 16)
-# define FMT_CLAMP_6BPC 0
-# define FMT_CLAMP_8BPC 1
-# define FMT_CLAMP_10BPC 2
-
/* Power management */
#define CG_SPLL_FUNC_CNTL 0x600
# define SPLL_RESET (1 << 0)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b1f990d..24f4960 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -98,7 +98,6 @@ extern int radeon_lockup_timeout;
extern int radeon_fastfb;
extern int radeon_dpm;
extern int radeon_aspm;
-extern int radeon_runtime_pm;
/*
* Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -328,6 +327,7 @@ struct radeon_fence_driver {
/* sync_seq is protected by ring emission lock */
uint64_t sync_seq[RADEON_NUM_RINGS];
atomic64_t last_seq;
+ unsigned long last_activity;
bool initialized;
};
@@ -348,7 +348,6 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, i
void radeon_fence_process(struct radeon_device *rdev, int ring);
bool radeon_fence_signaled(struct radeon_fence *fence);
int radeon_fence_wait(struct radeon_fence *fence, bool interruptible);
-int radeon_fence_wait_locked(struct radeon_fence *fence);
int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring);
int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
int radeon_fence_wait_any(struct radeon_device *rdev,
@@ -549,20 +548,17 @@ struct radeon_semaphore {
struct radeon_sa_bo *sa_bo;
signed waiters;
uint64_t gpu_addr;
- struct radeon_fence *sync_to[RADEON_NUM_RINGS];
};
int radeon_semaphore_create(struct radeon_device *rdev,
struct radeon_semaphore **semaphore);
-bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
+void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore);
-bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
+void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore);
-void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore,
- struct radeon_fence *fence);
int radeon_semaphore_sync_rings(struct radeon_device *rdev,
struct radeon_semaphore *semaphore,
- int waiting_ring);
+ int signaler, int waiter);
void radeon_semaphore_free(struct radeon_device *rdev,
struct radeon_semaphore **semaphore,
struct radeon_fence *fence);
@@ -649,15 +645,13 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg);
/*
* GPU doorbell structures, functions & helpers
*/
-#define RADEON_MAX_DOORBELLS 1024 /* Reserve at most 1024 doorbell slots for radeon-owned rings. */
-
struct radeon_doorbell {
+ u32 num_pages;
+ bool free[1024];
/* doorbell mmio */
- resource_size_t base;
- resource_size_t size;
- u32 __iomem *ptr;
- u32 num_doorbells; /* Number of doorbells actually reserved for radeon. */
- unsigned long used[DIV_ROUND_UP(RADEON_MAX_DOORBELLS, BITS_PER_LONG)];
+ resource_size_t base;
+ resource_size_t size;
+ void __iomem *ptr;
};
int radeon_doorbell_get(struct radeon_device *rdev, u32 *page);
@@ -771,6 +765,7 @@ struct radeon_ib {
struct radeon_fence *fence;
struct radeon_vm *vm;
bool is_const_ib;
+ struct radeon_fence *sync_to[RADEON_NUM_RINGS];
struct radeon_semaphore *semaphore;
};
@@ -804,7 +799,8 @@ struct radeon_ring {
u32 pipe;
u32 queue;
struct radeon_bo *mqd_obj;
- u32 doorbell_index;
+ u32 doorbell_page_num;
+ u32 doorbell_offset;
unsigned wptr_offs;
};
@@ -836,12 +832,6 @@ struct radeon_mec {
#define RADEON_VM_PTB_ALIGN_MASK (RADEON_VM_PTB_ALIGN_SIZE - 1)
#define RADEON_VM_PTB_ALIGN(a) (((a) + RADEON_VM_PTB_ALIGN_MASK) & ~RADEON_VM_PTB_ALIGN_MASK)
-#define R600_PTE_VALID (1 << 0)
-#define R600_PTE_SYSTEM (1 << 1)
-#define R600_PTE_SNOOPED (1 << 2)
-#define R600_PTE_READABLE (1 << 5)
-#define R600_PTE_WRITEABLE (1 << 6)
-
struct radeon_vm {
struct list_head list;
struct list_head va;
@@ -925,6 +915,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
struct radeon_ib *ib, struct radeon_vm *vm,
unsigned size);
void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib);
+void radeon_ib_sync_to(struct radeon_ib *ib, struct radeon_fence *fence);
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
struct radeon_ib *const_ib);
int radeon_ib_pool_init(struct radeon_device *rdev);
@@ -976,8 +967,12 @@ struct radeon_cs_reloc {
struct radeon_cs_chunk {
uint32_t chunk_id;
uint32_t length_dw;
+ int kpage_idx[2];
+ uint32_t *kpage[2];
uint32_t *kdata;
void __user *user_ptr;
+ int last_copied_page;
+ int last_page_index;
};
struct radeon_cs_parser {
@@ -1012,15 +1007,8 @@ struct radeon_cs_parser {
struct ww_acquire_ctx ticket;
};
-static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
-{
- struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
-
- if (ibc->kdata)
- return ibc->kdata[idx];
- return p->ib.ptr[idx];
-}
-
+extern int radeon_cs_finish_pages(struct radeon_cs_parser *p);
+extern u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx);
struct radeon_cs_packet {
unsigned idx;
@@ -1641,7 +1629,7 @@ struct radeon_asic_ring {
/* command emmit functions */
void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence);
- bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp,
+ void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp,
struct radeon_semaphore *semaphore, bool emit_wait);
void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
@@ -1687,6 +1675,8 @@ struct radeon_asic {
struct {
int (*init)(struct radeon_device *rdev);
void (*fini)(struct radeon_device *rdev);
+
+ u32 pt_ring_index;
void (*set_page)(struct radeon_device *rdev,
struct radeon_ib *ib,
uint64_t pe,
@@ -1982,7 +1972,6 @@ struct cik_asic {
unsigned tile_config;
uint32_t tile_mode_array[32];
- uint32_t macrotile_mode_array[16];
};
union radeon_asic_config {
@@ -2181,7 +2170,6 @@ struct radeon_device {
bool need_dma32;
bool accel_working;
bool fastfb_working; /* IGP feature*/
- bool needs_reset;
struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
const struct firmware *me_fw; /* all family ME firmware */
const struct firmware *pfp_fw; /* r6/700 PFP firmware */
@@ -2224,9 +2212,6 @@ struct radeon_device {
/* clock, powergating flags */
u32 cg_flags;
u32 pg_flags;
-
- struct dev_pm_domain vga_pm_domain;
- bool have_disp_power_ref;
};
int radeon_device_init(struct radeon_device *rdev,
@@ -2243,8 +2228,8 @@ void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v,
u32 r100_io_rreg(struct radeon_device *rdev, u32 reg);
void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v);
-u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index);
-void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v);
+u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 offset);
+void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v);
/*
* Cast helper
@@ -2307,8 +2292,8 @@ void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v);
#define RREG32_IO(reg) r100_io_rreg(rdev, (reg))
#define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v))
-#define RDOORBELL32(index) cik_mm_rdoorbell(rdev, (index))
-#define WDOORBELL32(index, v) cik_mm_wdoorbell(rdev, (index), (v))
+#define RDOORBELL32(offset) cik_mm_rdoorbell(rdev, (offset))
+#define WDOORBELL32(offset, v) cik_mm_wdoorbell(rdev, (offset), (v))
/*
* Indirect registers accessor
@@ -2688,8 +2673,8 @@ extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base);
extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
-extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
-extern int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon);
+extern int radeon_resume_kms(struct drm_device *dev);
+extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size);
extern void radeon_program_register_sequence(struct radeon_device *rdev,
const u32 *registers,
@@ -2710,10 +2695,10 @@ void radeon_vm_fence(struct radeon_device *rdev,
struct radeon_vm *vm,
struct radeon_fence *fence);
uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr);
-int radeon_vm_bo_update(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo,
- struct ttm_mem_reg *mem);
+int radeon_vm_bo_update_pte(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_bo *bo,
+ struct ttm_mem_reg *mem);
void radeon_vm_bo_invalidate(struct radeon_device *rdev,
struct radeon_bo *bo);
struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 98a9074..10f98c7 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -369,7 +369,7 @@ int radeon_atif_handler(struct radeon_device *rdev,
return NOTIFY_DONE;
/* Check pending SBIOS requests */
- handle = ACPI_HANDLE(&rdev->pdev->dev);
+ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
count = radeon_atif_get_sbios_requests(handle, &req);
if (count <= 0)
@@ -556,7 +556,7 @@ int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev)
struct radeon_atcs *atcs = &rdev->atcs;
/* Get the device handle */
- handle = ACPI_HANDLE(&rdev->pdev->dev);
+ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
if (!handle)
return -EINVAL;
@@ -596,7 +596,7 @@ int radeon_acpi_pcie_performance_request(struct radeon_device *rdev,
u32 retry = 3;
/* Get the device handle */
- handle = ACPI_HANDLE(&rdev->pdev->dev);
+ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
if (!handle)
return -EINVAL;
@@ -699,7 +699,7 @@ int radeon_acpi_init(struct radeon_device *rdev)
int ret;
/* Get the device handle */
- handle = ACPI_HANDLE(&rdev->pdev->dev);
+ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
/* No need to proceed if we're sure that ATIF is not supported */
if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index e354ce9..8f7e045 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1622,7 +1622,8 @@ static struct radeon_asic cayman_asic = {
.vm = {
.init = &cayman_vm_init,
.fini = &cayman_vm_fini,
- .set_page = &cayman_dma_vm_set_page,
+ .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .set_page = &cayman_vm_set_page,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring,
@@ -1722,7 +1723,8 @@ static struct radeon_asic trinity_asic = {
.vm = {
.init = &cayman_vm_init,
.fini = &cayman_vm_fini,
- .set_page = &cayman_dma_vm_set_page,
+ .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .set_page = &cayman_vm_set_page,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring,
@@ -1852,7 +1854,8 @@ static struct radeon_asic si_asic = {
.vm = {
.init = &si_vm_init,
.fini = &si_vm_fini,
- .set_page = &si_dma_vm_set_page,
+ .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .set_page = &si_vm_set_page,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &si_gfx_ring,
@@ -1876,7 +1879,7 @@ static struct radeon_asic si_asic = {
.hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
- .blit = &r600_copy_cpdma,
+ .blit = NULL,
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
.dma = &si_copy_dma,
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
@@ -1997,7 +2000,8 @@ static struct radeon_asic ci_asic = {
.vm = {
.init = &cik_vm_init,
.fini = &cik_vm_fini,
- .set_page = &cik_sdma_vm_set_page,
+ .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .set_page = &cik_vm_set_page,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring,
@@ -2015,8 +2019,6 @@ static struct radeon_asic ci_asic = {
.bandwidth_update = &dce8_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
- .set_backlight_level = &atombios_set_backlight_level,
- .get_backlight_level = &atombios_get_backlight_level,
.hdmi_enable = &evergreen_hdmi_enable,
.hdmi_setmode = &evergreen_hdmi_setmode,
},
@@ -2098,7 +2100,8 @@ static struct radeon_asic kv_asic = {
.vm = {
.init = &cik_vm_init,
.fini = &cik_vm_fini,
- .set_page = &cik_sdma_vm_set_page,
+ .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .set_page = &cik_vm_set_page,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring,
@@ -2116,8 +2119,6 @@ static struct radeon_asic kv_asic = {
.bandwidth_update = &dce8_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
- .set_backlight_level = &atombios_set_backlight_level,
- .get_backlight_level = &atombios_get_backlight_level,
.hdmi_enable = &evergreen_hdmi_enable,
.hdmi_setmode = &evergreen_hdmi_setmode,
},
@@ -2441,48 +2442,27 @@ int radeon_asic_init(struct radeon_device *rdev)
}
break;
case CHIP_BONAIRE:
- case CHIP_HAWAII:
rdev->asic = &ci_asic;
rdev->num_crtc = 6;
rdev->has_uvd = true;
- if (rdev->family == CHIP_BONAIRE) {
- rdev->cg_flags =
- RADEON_CG_SUPPORT_GFX_MGCG |
- RADEON_CG_SUPPORT_GFX_MGLS |
- /*RADEON_CG_SUPPORT_GFX_CGCG |*/
- RADEON_CG_SUPPORT_GFX_CGLS |
- RADEON_CG_SUPPORT_GFX_CGTS |
- RADEON_CG_SUPPORT_GFX_CGTS_LS |
- RADEON_CG_SUPPORT_GFX_CP_LS |
- RADEON_CG_SUPPORT_MC_LS |
- RADEON_CG_SUPPORT_MC_MGCG |
- RADEON_CG_SUPPORT_SDMA_MGCG |
- RADEON_CG_SUPPORT_SDMA_LS |
- RADEON_CG_SUPPORT_BIF_LS |
- RADEON_CG_SUPPORT_VCE_MGCG |
- RADEON_CG_SUPPORT_UVD_MGCG |
- RADEON_CG_SUPPORT_HDP_LS |
- RADEON_CG_SUPPORT_HDP_MGCG;
- rdev->pg_flags = 0;
- } else {
- rdev->cg_flags =
- RADEON_CG_SUPPORT_GFX_MGCG |
- RADEON_CG_SUPPORT_GFX_MGLS |
- /*RADEON_CG_SUPPORT_GFX_CGCG |*/
- RADEON_CG_SUPPORT_GFX_CGLS |
- RADEON_CG_SUPPORT_GFX_CGTS |
- RADEON_CG_SUPPORT_GFX_CP_LS |
- RADEON_CG_SUPPORT_MC_LS |
- RADEON_CG_SUPPORT_MC_MGCG |
- RADEON_CG_SUPPORT_SDMA_MGCG |
- RADEON_CG_SUPPORT_SDMA_LS |
- RADEON_CG_SUPPORT_BIF_LS |
- RADEON_CG_SUPPORT_VCE_MGCG |
- RADEON_CG_SUPPORT_UVD_MGCG |
- RADEON_CG_SUPPORT_HDP_LS |
- RADEON_CG_SUPPORT_HDP_MGCG;
- rdev->pg_flags = 0;
- }
+ rdev->cg_flags =
+ RADEON_CG_SUPPORT_GFX_MGCG |
+ RADEON_CG_SUPPORT_GFX_MGLS |
+ /*RADEON_CG_SUPPORT_GFX_CGCG |*/
+ RADEON_CG_SUPPORT_GFX_CGLS |
+ RADEON_CG_SUPPORT_GFX_CGTS |
+ RADEON_CG_SUPPORT_GFX_CGTS_LS |
+ RADEON_CG_SUPPORT_GFX_CP_LS |
+ RADEON_CG_SUPPORT_MC_LS |
+ RADEON_CG_SUPPORT_MC_MGCG |
+ RADEON_CG_SUPPORT_SDMA_MGCG |
+ RADEON_CG_SUPPORT_SDMA_LS |
+ RADEON_CG_SUPPORT_BIF_LS |
+ RADEON_CG_SUPPORT_VCE_MGCG |
+ RADEON_CG_SUPPORT_UVD_MGCG |
+ RADEON_CG_SUPPORT_HDP_LS |
+ RADEON_CG_SUPPORT_HDP_MGCG;
+ rdev->pg_flags = 0;
break;
case CHIP_KAVERI:
case CHIP_KABINI:
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index c9fd97b..70c29d5 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -80,7 +80,7 @@ int r100_irq_set(struct radeon_device *rdev);
int r100_irq_process(struct radeon_device *rdev);
void r100_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
-bool r100_semaphore_ring_emit(struct radeon_device *rdev,
+void r100_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *cp,
struct radeon_semaphore *semaphore,
bool emit_wait);
@@ -313,13 +313,13 @@ int r600_cs_parse(struct radeon_cs_parser *p);
int r600_dma_cs_parse(struct radeon_cs_parser *p);
void r600_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
-bool r600_semaphore_ring_emit(struct radeon_device *rdev,
+void r600_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *cp,
struct radeon_semaphore *semaphore,
bool emit_wait);
void r600_dma_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
-bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
+void r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait);
@@ -566,6 +566,10 @@ int sumo_dpm_force_performance_level(struct radeon_device *rdev,
*/
void cayman_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
+void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
+ struct radeon_ring *ring,
+ struct radeon_semaphore *semaphore,
+ bool emit_wait);
void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev);
int cayman_init(struct radeon_device *rdev);
void cayman_fini(struct radeon_device *rdev);
@@ -577,18 +581,17 @@ int cayman_vm_init(struct radeon_device *rdev);
void cayman_vm_fini(struct radeon_device *rdev);
void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags);
+void cayman_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
struct radeon_ib *ib);
bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
-void cayman_dma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags);
-
void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
int ni_dpm_init(struct radeon_device *rdev);
@@ -650,17 +653,17 @@ int si_irq_set(struct radeon_device *rdev);
int si_irq_process(struct radeon_device *rdev);
int si_vm_init(struct radeon_device *rdev);
void si_vm_fini(struct radeon_device *rdev);
+void si_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
int si_copy_dma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages,
struct radeon_fence **fence);
-void si_dma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags);
void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
u32 si_get_xclk(struct radeon_device *rdev);
uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev);
@@ -693,7 +696,7 @@ void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
-bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
+void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait);
@@ -702,10 +705,6 @@ int cik_copy_dma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages,
struct radeon_fence **fence);
-int cik_copy_cpdma(struct radeon_device *rdev,
- uint64_t src_offset, uint64_t dst_offset,
- unsigned num_gpu_pages,
- struct radeon_fence **fence);
int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
@@ -713,7 +712,7 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
void cik_fence_compute_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
-bool cik_semaphore_ring_emit(struct radeon_device *rdev,
+void cik_semaphore_ring_emit(struct radeon_device *rdev,
struct radeon_ring *cp,
struct radeon_semaphore *semaphore,
bool emit_wait);
@@ -732,11 +731,11 @@ int cik_irq_process(struct radeon_device *rdev);
int cik_vm_init(struct radeon_device *rdev);
void cik_vm_fini(struct radeon_device *rdev);
void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
-void cik_sdma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags);
+void cik_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
@@ -803,7 +802,7 @@ void uvd_v1_0_stop(struct radeon_device *rdev);
int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
-bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
+void uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait);
@@ -815,7 +814,7 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev,
struct radeon_fence *fence);
/* uvd v3.1 */
-bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
+void uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 5c39bf7..f79ee18 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2918,7 +2918,7 @@ int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
mpll_param->dll_speed = args.ucDllSpeed;
mpll_param->bwcntl = args.ucBWCntl;
mpll_param->vco_mode =
- (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK);
+ (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK) ? 1 : 0;
mpll_param->yclk_sel =
(args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;
mpll_param->qdr =
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 9d302ea..d96070b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -8,7 +8,8 @@
*/
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
-#include <linux/acpi.h>
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
#include <linux/pci.h>
#include "radeon_acpi.h"
@@ -58,10 +59,6 @@ struct atpx_mux {
u16 mux;
} __packed;
-bool radeon_is_px(void) {
- return radeon_atpx_priv.atpx_detected;
-}
-
/**
* radeon_atpx_call - call an ATPX method
*
@@ -446,7 +443,7 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
acpi_handle dhandle, atpx_handle;
acpi_status status;
- dhandle = ACPI_HANDLE(&pdev->dev);
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
return false;
@@ -492,7 +489,7 @@ static int radeon_atpx_init(void)
*/
static int radeon_atpx_get_client_id(struct pci_dev *pdev)
{
- if (radeon_atpx_priv.dhandle == ACPI_HANDLE(&pdev->dev))
+ if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
return VGA_SWITCHEROO_IGD;
else
return VGA_SWITCHEROO_DIS;
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index b3633d9..061b227 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -185,7 +185,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
return false;
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
- dhandle = ACPI_HANDLE(&pdev->dev);
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
continue;
@@ -499,7 +499,7 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev)
crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
fp2_gen_cntl = 0;
- if (rdev->ddev->pdev->device == PCI_DEVICE_ID_ATI_RADEON_QY) {
+ if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) {
fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
}
@@ -536,7 +536,7 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev)
(RADEON_CRTC_SYNC_TRISTAT |
RADEON_CRTC_DISPLAY_DIS)));
- if (rdev->ddev->pdev->device == PCI_DEVICE_ID_ATI_RADEON_QY) {
+ if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) {
WREG32(RADEON_FP2_GEN_CNTL, (fp2_gen_cntl & ~RADEON_FP2_ON));
}
@@ -554,7 +554,7 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev)
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
}
WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
- if (rdev->ddev->pdev->device == PCI_DEVICE_ID_ATI_RADEON_QY) {
+ if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) {
WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
}
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 20a768a..6456573 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -31,8 +31,6 @@
#include "radeon.h"
#include "atom.h"
-#include <linux/pm_runtime.h>
-
extern void
radeon_combios_connected_scratch_regs(struct drm_connector *connector,
struct drm_encoder *encoder,
@@ -413,21 +411,6 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
}
}
- if (property == rdev->mode_info.dither_property) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- /* need to find digital encoder on connector */
- encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
- if (!encoder)
- return 0;
-
- radeon_encoder = to_radeon_encoder(encoder);
-
- if (radeon_connector->dither != val) {
- radeon_connector->dither = val;
- radeon_property_change_mode(&radeon_encoder->base);
- }
- }
-
if (property == rdev->mode_info.underscan_property) {
/* need to find digital encoder on connector */
encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
@@ -643,11 +626,6 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
enum drm_connector_status ret = connector_status_disconnected;
- int r;
-
- r = pm_runtime_get_sync(connector->dev->dev);
- if (r < 0)
- return connector_status_disconnected;
if (encoder) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -673,8 +651,6 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
/* check acpi lid status ??? */
radeon_connector_update_scratch_regs(connector, ret);
- pm_runtime_mark_last_busy(connector->dev->dev);
- pm_runtime_put_autosuspend(connector->dev->dev);
return ret;
}
@@ -774,11 +750,6 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
struct drm_encoder_helper_funcs *encoder_funcs;
bool dret = false;
enum drm_connector_status ret = connector_status_disconnected;
- int r;
-
- r = pm_runtime_get_sync(connector->dev->dev);
- if (r < 0)
- return connector_status_disconnected;
encoder = radeon_best_single_encoder(connector);
if (!encoder)
@@ -819,8 +790,9 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
* detected a monitor via load.
*/
if (radeon_connector->detected_by_load)
- ret = connector->status;
- goto out;
+ return connector->status;
+ else
+ return ret;
}
if (radeon_connector->dac_load_detect && encoder) {
@@ -845,11 +817,6 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
}
radeon_connector_update_scratch_regs(connector, ret);
-
-out:
- pm_runtime_mark_last_busy(connector->dev->dev);
- pm_runtime_put_autosuspend(connector->dev->dev);
-
return ret;
}
@@ -906,15 +873,10 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
struct drm_encoder_helper_funcs *encoder_funcs;
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected;
- int r;
if (!radeon_connector->dac_load_detect)
return ret;
- r = pm_runtime_get_sync(connector->dev->dev);
- if (r < 0)
- return connector_status_disconnected;
-
encoder = radeon_best_single_encoder(connector);
if (!encoder)
ret = connector_status_disconnected;
@@ -925,8 +887,6 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
if (ret == connector_status_connected)
ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
radeon_connector_update_scratch_regs(connector, ret);
- pm_runtime_mark_last_busy(connector->dev->dev);
- pm_runtime_put_autosuspend(connector->dev->dev);
return ret;
}
@@ -994,18 +954,12 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
struct drm_encoder *encoder = NULL;
struct drm_encoder_helper_funcs *encoder_funcs;
struct drm_mode_object *obj;
- int i, r;
+ int i;
enum drm_connector_status ret = connector_status_disconnected;
bool dret = false, broken_edid = false;
- r = pm_runtime_get_sync(connector->dev->dev);
- if (r < 0)
- return connector_status_disconnected;
-
- if (!force && radeon_check_hpd_status_unchanged(connector)) {
- ret = connector->status;
- goto exit;
- }
+ if (!force && radeon_check_hpd_status_unchanged(connector))
+ return connector->status;
if (radeon_connector->ddc_bus)
dret = radeon_ddc_probe(radeon_connector, false);
@@ -1156,11 +1110,6 @@ out:
/* updated in get modes as well since we need to know if it's analog or digital */
radeon_connector_update_scratch_regs(connector, ret);
-
-exit:
- pm_runtime_mark_last_busy(connector->dev->dev);
- pm_runtime_put_autosuspend(connector->dev->dev);
-
return ret;
}
@@ -1428,16 +1377,9 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
enum drm_connector_status ret = connector_status_disconnected;
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
- int r;
- r = pm_runtime_get_sync(connector->dev->dev);
- if (r < 0)
- return connector_status_disconnected;
-
- if (!force && radeon_check_hpd_status_unchanged(connector)) {
- ret = connector->status;
- goto out;
- }
+ if (!force && radeon_check_hpd_status_unchanged(connector))
+ return connector->status;
if (radeon_connector->edid) {
kfree(radeon_connector->edid);
@@ -1501,10 +1443,6 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
}
radeon_connector_update_scratch_regs(connector, ret);
-out:
- pm_runtime_mark_last_busy(connector->dev->dev);
- pm_runtime_put_autosuspend(connector->dev->dev);
-
return ret;
}
@@ -1720,16 +1658,12 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.underscan_vborder_property,
0);
-
- drm_object_attach_property(&radeon_connector->base.base,
- rdev->mode_info.dither_property,
- RADEON_FMT_DITHER_DISABLE);
-
if (radeon_audio != 0)
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
- RADEON_AUDIO_AUTO);
-
+ (radeon_audio == 1) ?
+ RADEON_AUDIO_AUTO :
+ RADEON_AUDIO_DISABLE);
subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
@@ -1826,12 +1760,9 @@ radeon_add_atom_connector(struct drm_device *dev,
if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
- RADEON_AUDIO_AUTO);
- }
- if (ASIC_IS_AVIVO(rdev)) {
- drm_object_attach_property(&radeon_connector->base.base,
- rdev->mode_info.dither_property,
- RADEON_FMT_DITHER_DISABLE);
+ (radeon_audio == 1) ?
+ RADEON_AUDIO_AUTO :
+ RADEON_AUDIO_DISABLE);
}
if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true;
@@ -1876,12 +1807,9 @@ radeon_add_atom_connector(struct drm_device *dev,
if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
- RADEON_AUDIO_AUTO);
- }
- if (ASIC_IS_AVIVO(rdev)) {
- drm_object_attach_property(&radeon_connector->base.base,
- rdev->mode_info.dither_property,
- RADEON_FMT_DITHER_DISABLE);
+ (radeon_audio == 1) ?
+ RADEON_AUDIO_AUTO :
+ RADEON_AUDIO_DISABLE);
}
subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true;
@@ -1925,13 +1853,9 @@ radeon_add_atom_connector(struct drm_device *dev,
if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
- RADEON_AUDIO_AUTO);
- }
- if (ASIC_IS_AVIVO(rdev)) {
- drm_object_attach_property(&radeon_connector->base.base,
- rdev->mode_info.dither_property,
- RADEON_FMT_DITHER_DISABLE);
-
+ (radeon_audio == 1) ?
+ RADEON_AUDIO_AUTO :
+ RADEON_AUDIO_DISABLE);
}
connector->interlace_allowed = true;
/* in theory with a DP to VGA converter... */
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 0b36616..80285e3 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -159,8 +159,7 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
if (!p->relocs[i].robj)
continue;
- radeon_semaphore_sync_to(p->ib.semaphore,
- p->relocs[i].robj->tbo.sync_obj);
+ radeon_ib_sync_to(&p->ib, p->relocs[i].robj->tbo.sync_obj);
}
}
@@ -213,7 +212,9 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
return -EFAULT;
}
p->chunks[i].length_dw = user_chunk.length_dw;
+ p->chunks[i].kdata = NULL;
p->chunks[i].chunk_id = user_chunk.chunk_id;
+ p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data;
if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) {
p->chunk_relocs_idx = i;
}
@@ -236,31 +237,25 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
return -EINVAL;
}
- size = p->chunks[i].length_dw;
- cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
- p->chunks[i].user_ptr = cdata;
- if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB)
- continue;
-
- if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) {
- if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP))
- continue;
- }
-
- p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
- size *= sizeof(uint32_t);
- if (p->chunks[i].kdata == NULL) {
- return -ENOMEM;
- }
- if (DRM_COPY_FROM_USER(p->chunks[i].kdata, cdata, size)) {
- return -EFAULT;
- }
- if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
- p->cs_flags = p->chunks[i].kdata[0];
- if (p->chunks[i].length_dw > 1)
- ring = p->chunks[i].kdata[1];
- if (p->chunks[i].length_dw > 2)
- priority = (s32)p->chunks[i].kdata[2];
+ cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data;
+ if ((p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) ||
+ (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS)) {
+ size = p->chunks[i].length_dw * sizeof(uint32_t);
+ p->chunks[i].kdata = kmalloc(size, GFP_KERNEL);
+ if (p->chunks[i].kdata == NULL) {
+ return -ENOMEM;
+ }
+ if (DRM_COPY_FROM_USER(p->chunks[i].kdata,
+ p->chunks[i].user_ptr, size)) {
+ return -EFAULT;
+ }
+ if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
+ p->cs_flags = p->chunks[i].kdata[0];
+ if (p->chunks[i].length_dw > 1)
+ ring = p->chunks[i].kdata[1];
+ if (p->chunks[i].length_dw > 2)
+ priority = (s32)p->chunks[i].kdata[2];
+ }
}
}
@@ -283,6 +278,34 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
}
}
+ /* deal with non-vm */
+ if ((p->chunk_ib_idx != -1) &&
+ ((p->cs_flags & RADEON_CS_USE_VM) == 0) &&
+ (p->chunks[p->chunk_ib_idx].chunk_id == RADEON_CHUNK_ID_IB)) {
+ if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) {
+ DRM_ERROR("cs IB too big: %d\n",
+ p->chunks[p->chunk_ib_idx].length_dw);
+ return -EINVAL;
+ }
+ if (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) {
+ p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL ||
+ p->chunks[p->chunk_ib_idx].kpage[1] == NULL) {
+ kfree(p->chunks[p->chunk_ib_idx].kpage[0]);
+ kfree(p->chunks[p->chunk_ib_idx].kpage[1]);
+ p->chunks[p->chunk_ib_idx].kpage[0] = NULL;
+ p->chunks[p->chunk_ib_idx].kpage[1] = NULL;
+ return -ENOMEM;
+ }
+ }
+ p->chunks[p->chunk_ib_idx].kpage_idx[0] = -1;
+ p->chunks[p->chunk_ib_idx].kpage_idx[1] = -1;
+ p->chunks[p->chunk_ib_idx].last_copied_page = -1;
+ p->chunks[p->chunk_ib_idx].last_page_index =
+ ((p->chunks[p->chunk_ib_idx].length_dw * 4) - 1) / PAGE_SIZE;
+ }
+
return 0;
}
@@ -316,8 +339,13 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
kfree(parser->track);
kfree(parser->relocs);
kfree(parser->relocs_ptr);
- for (i = 0; i < parser->nchunks; i++)
- drm_free_large(parser->chunks[i].kdata);
+ for (i = 0; i < parser->nchunks; i++) {
+ kfree(parser->chunks[i].kdata);
+ if ((parser->rdev->flags & RADEON_IS_AGP)) {
+ kfree(parser->chunks[i].kpage[0]);
+ kfree(parser->chunks[i].kpage[1]);
+ }
+ }
kfree(parser->chunks);
kfree(parser->chunks_array);
radeon_ib_free(parser->rdev, &parser->ib);
@@ -327,6 +355,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
static int radeon_cs_ib_chunk(struct radeon_device *rdev,
struct radeon_cs_parser *parser)
{
+ struct radeon_cs_chunk *ib_chunk;
int r;
if (parser->chunk_ib_idx == -1)
@@ -335,11 +364,28 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
if (parser->cs_flags & RADEON_CS_USE_VM)
return 0;
+ ib_chunk = &parser->chunks[parser->chunk_ib_idx];
+ /* Copy the packet into the IB, the parser will read from the
+ * input memory (cached) and write to the IB (which can be
+ * uncached).
+ */
+ r = radeon_ib_get(rdev, parser->ring, &parser->ib,
+ NULL, ib_chunk->length_dw * 4);
+ if (r) {
+ DRM_ERROR("Failed to get ib !\n");
+ return r;
+ }
+ parser->ib.length_dw = ib_chunk->length_dw;
r = radeon_cs_parse(rdev, parser->ring, parser);
if (r || parser->parser_error) {
DRM_ERROR("Invalid command stream !\n");
return r;
}
+ r = radeon_cs_finish_pages(parser);
+ if (r) {
+ DRM_ERROR("Invalid command stream !\n");
+ return r;
+ }
if (parser->ring == R600_RING_TYPE_UVD_INDEX)
radeon_uvd_note_usage(rdev);
@@ -360,13 +406,13 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser,
struct radeon_bo *bo;
int r;
- r = radeon_vm_bo_update(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem);
+ r = radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem);
if (r) {
return r;
}
list_for_each_entry(lobj, &parser->validated, tv.head) {
bo = lobj->bo;
- r = radeon_vm_bo_update(parser->rdev, vm, bo, &bo->tbo.mem);
+ r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem);
if (r) {
return r;
}
@@ -377,6 +423,7 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser,
static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
struct radeon_cs_parser *parser)
{
+ struct radeon_cs_chunk *ib_chunk;
struct radeon_fpriv *fpriv = parser->filp->driver_priv;
struct radeon_vm *vm = &fpriv->vm;
int r;
@@ -386,13 +433,49 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
if ((parser->cs_flags & RADEON_CS_USE_VM) == 0)
return 0;
- if (parser->const_ib.length_dw) {
+ if ((rdev->family >= CHIP_TAHITI) &&
+ (parser->chunk_const_ib_idx != -1)) {
+ ib_chunk = &parser->chunks[parser->chunk_const_ib_idx];
+ if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
+ DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw);
+ return -EINVAL;
+ }
+ r = radeon_ib_get(rdev, parser->ring, &parser->const_ib,
+ vm, ib_chunk->length_dw * 4);
+ if (r) {
+ DRM_ERROR("Failed to get const ib !\n");
+ return r;
+ }
+ parser->const_ib.is_const_ib = true;
+ parser->const_ib.length_dw = ib_chunk->length_dw;
+ /* Copy the packet into the IB */
+ if (DRM_COPY_FROM_USER(parser->const_ib.ptr, ib_chunk->user_ptr,
+ ib_chunk->length_dw * 4)) {
+ return -EFAULT;
+ }
r = radeon_ring_ib_parse(rdev, parser->ring, &parser->const_ib);
if (r) {
return r;
}
}
+ ib_chunk = &parser->chunks[parser->chunk_ib_idx];
+ if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
+ DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw);
+ return -EINVAL;
+ }
+ r = radeon_ib_get(rdev, parser->ring, &parser->ib,
+ vm, ib_chunk->length_dw * 4);
+ if (r) {
+ DRM_ERROR("Failed to get ib !\n");
+ return r;
+ }
+ parser->ib.length_dw = ib_chunk->length_dw;
+ /* Copy the packet into the IB */
+ if (DRM_COPY_FROM_USER(parser->ib.ptr, ib_chunk->user_ptr,
+ ib_chunk->length_dw * 4)) {
+ return -EFAULT;
+ }
r = radeon_ring_ib_parse(rdev, parser->ring, &parser->ib);
if (r) {
return r;
@@ -412,9 +495,9 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
goto out;
}
radeon_cs_sync_rings(parser);
- radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence);
- radeon_semaphore_sync_to(parser->ib.semaphore,
- radeon_vm_grab_id(rdev, vm, parser->ring));
+ radeon_ib_sync_to(&parser->ib, vm->fence);
+ radeon_ib_sync_to(&parser->ib, radeon_vm_grab_id(
+ rdev, vm, parser->ring));
if ((rdev->family >= CHIP_TAHITI) &&
(parser->chunk_const_ib_idx != -1)) {
@@ -444,62 +527,6 @@ static int radeon_cs_handle_lockup(struct radeon_device *rdev, int r)
return r;
}
-static int radeon_cs_ib_fill(struct radeon_device *rdev, struct radeon_cs_parser *parser)
-{
- struct radeon_cs_chunk *ib_chunk;
- struct radeon_vm *vm = NULL;
- int r;
-
- if (parser->chunk_ib_idx == -1)
- return 0;
-
- if (parser->cs_flags & RADEON_CS_USE_VM) {
- struct radeon_fpriv *fpriv = parser->filp->driver_priv;
- vm = &fpriv->vm;
-
- if ((rdev->family >= CHIP_TAHITI) &&
- (parser->chunk_const_ib_idx != -1)) {
- ib_chunk = &parser->chunks[parser->chunk_const_ib_idx];
- if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
- DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw);
- return -EINVAL;
- }
- r = radeon_ib_get(rdev, parser->ring, &parser->const_ib,
- vm, ib_chunk->length_dw * 4);
- if (r) {
- DRM_ERROR("Failed to get const ib !\n");
- return r;
- }
- parser->const_ib.is_const_ib = true;
- parser->const_ib.length_dw = ib_chunk->length_dw;
- if (DRM_COPY_FROM_USER(parser->const_ib.ptr,
- ib_chunk->user_ptr,
- ib_chunk->length_dw * 4))
- return -EFAULT;
- }
-
- ib_chunk = &parser->chunks[parser->chunk_ib_idx];
- if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
- DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw);
- return -EINVAL;
- }
- }
- ib_chunk = &parser->chunks[parser->chunk_ib_idx];
-
- r = radeon_ib_get(rdev, parser->ring, &parser->ib,
- vm, ib_chunk->length_dw * 4);
- if (r) {
- DRM_ERROR("Failed to get ib !\n");
- return r;
- }
- parser->ib.length_dw = ib_chunk->length_dw;
- if (ib_chunk->kdata)
- memcpy(parser->ib.ptr, ib_chunk->kdata, ib_chunk->length_dw * 4);
- else if (DRM_COPY_FROM_USER(parser->ib.ptr, ib_chunk->user_ptr, ib_chunk->length_dw * 4))
- return -EFAULT;
- return 0;
-}
-
int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{
struct radeon_device *rdev = dev->dev_private;
@@ -525,15 +552,10 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
r = radeon_cs_handle_lockup(rdev, r);
return r;
}
-
- r = radeon_cs_ib_fill(rdev, &parser);
- if (!r) {
- r = radeon_cs_parser_relocs(&parser);
- if (r && r != -ERESTARTSYS)
- DRM_ERROR("Failed to parse relocation %d!\n", r);
- }
-
+ r = radeon_cs_parser_relocs(&parser);
if (r) {
+ if (r != -ERESTARTSYS)
+ DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r, false);
up_read(&rdev->exclusive_lock);
r = radeon_cs_handle_lockup(rdev, r);
@@ -557,6 +579,97 @@ out:
return r;
}
+int radeon_cs_finish_pages(struct radeon_cs_parser *p)
+{
+ struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
+ int i;
+ int size = PAGE_SIZE;
+
+ for (i = ibc->last_copied_page + 1; i <= ibc->last_page_index; i++) {
+ if (i == ibc->last_page_index) {
+ size = (ibc->length_dw * 4) % PAGE_SIZE;
+ if (size == 0)
+ size = PAGE_SIZE;
+ }
+
+ if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)),
+ ibc->user_ptr + (i * PAGE_SIZE),
+ size))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx)
+{
+ int new_page;
+ struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
+ int i;
+ int size = PAGE_SIZE;
+ bool copy1 = (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) ?
+ false : true;
+
+ for (i = ibc->last_copied_page + 1; i < pg_idx; i++) {
+ if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)),
+ ibc->user_ptr + (i * PAGE_SIZE),
+ PAGE_SIZE)) {
+ p->parser_error = -EFAULT;
+ return 0;
+ }
+ }
+
+ if (pg_idx == ibc->last_page_index) {
+ size = (ibc->length_dw * 4) % PAGE_SIZE;
+ if (size == 0)
+ size = PAGE_SIZE;
+ }
+
+ new_page = ibc->kpage_idx[0] < ibc->kpage_idx[1] ? 0 : 1;
+ if (copy1)
+ ibc->kpage[new_page] = p->ib.ptr + (pg_idx * (PAGE_SIZE / 4));
+
+ if (DRM_COPY_FROM_USER(ibc->kpage[new_page],
+ ibc->user_ptr + (pg_idx * PAGE_SIZE),
+ size)) {
+ p->parser_error = -EFAULT;
+ return 0;
+ }
+
+ /* copy to IB for non single case */
+ if (!copy1)
+ memcpy((void *)(p->ib.ptr+(pg_idx*(PAGE_SIZE/4))), ibc->kpage[new_page], size);
+
+ ibc->last_copied_page = pg_idx;
+ ibc->kpage_idx[new_page] = pg_idx;
+
+ return new_page;
+}
+
+u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
+{
+ struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
+ u32 pg_idx, pg_offset;
+ u32 idx_value = 0;
+ int new_page;
+
+ pg_idx = (idx * 4) / PAGE_SIZE;
+ pg_offset = (idx * 4) % PAGE_SIZE;
+
+ if (ibc->kpage_idx[0] == pg_idx)
+ return ibc->kpage[0][pg_offset/4];
+ if (ibc->kpage_idx[1] == pg_idx)
+ return ibc->kpage[1][pg_offset/4];
+
+ new_page = radeon_cs_update_pages(p, pg_idx);
+ if (new_page < 0) {
+ p->parser_error = new_page;
+ return 0;
+ }
+
+ idx_value = ibc->kpage[new_page][pg_offset/4];
+ return idx_value;
+}
+
/**
* radeon_cs_packet_parse() - parse cp packet and point ib index to next packet
* @parser: parser structure holding parsing context.
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 39b033b..841d0e0 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -98,16 +98,9 @@ static const char radeon_family_name[][16] = {
"BONAIRE",
"KAVERI",
"KABINI",
- "HAWAII",
"LAST",
};
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
-#else
-static inline bool radeon_is_px(void) { return false; }
-#endif
-
/**
* radeon_program_register_sequence - program an array of registers.
*
@@ -251,23 +244,28 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
*/
int radeon_doorbell_init(struct radeon_device *rdev)
{
+ int i;
+
/* doorbell bar mapping */
rdev->doorbell.base = pci_resource_start(rdev->pdev, 2);
rdev->doorbell.size = pci_resource_len(rdev->pdev, 2);
- rdev->doorbell.num_doorbells = min_t(u32, rdev->doorbell.size / sizeof(u32), RADEON_MAX_DOORBELLS);
- if (rdev->doorbell.num_doorbells == 0)
- return -EINVAL;
+ /* limit to 4 MB for now */
+ if (rdev->doorbell.size > (4 * 1024 * 1024))
+ rdev->doorbell.size = 4 * 1024 * 1024;
- rdev->doorbell.ptr = ioremap(rdev->doorbell.base, rdev->doorbell.num_doorbells * sizeof(u32));
+ rdev->doorbell.ptr = ioremap(rdev->doorbell.base, rdev->doorbell.size);
if (rdev->doorbell.ptr == NULL) {
return -ENOMEM;
}
DRM_INFO("doorbell mmio base: 0x%08X\n", (uint32_t)rdev->doorbell.base);
DRM_INFO("doorbell mmio size: %u\n", (unsigned)rdev->doorbell.size);
- memset(&rdev->doorbell.used, 0, sizeof(rdev->doorbell.used));
+ rdev->doorbell.num_pages = rdev->doorbell.size / PAGE_SIZE;
+ for (i = 0; i < rdev->doorbell.num_pages; i++) {
+ rdev->doorbell.free[i] = true;
+ }
return 0;
}
@@ -285,38 +283,40 @@ void radeon_doorbell_fini(struct radeon_device *rdev)
}
/**
- * radeon_doorbell_get - Allocate a doorbell entry
+ * radeon_doorbell_get - Allocate a doorbell page
*
* @rdev: radeon_device pointer
- * @doorbell: doorbell index
+ * @doorbell: doorbell page number
*
- * Allocate a doorbell for use by the driver (all asics).
+ * Allocate a doorbell page for use by the driver (all asics).
* Returns 0 on success or -EINVAL on failure.
*/
int radeon_doorbell_get(struct radeon_device *rdev, u32 *doorbell)
{
- unsigned long offset = find_first_zero_bit(rdev->doorbell.used, rdev->doorbell.num_doorbells);
- if (offset < rdev->doorbell.num_doorbells) {
- __set_bit(offset, rdev->doorbell.used);
- *doorbell = offset;
- return 0;
- } else {
- return -EINVAL;
+ int i;
+
+ for (i = 0; i < rdev->doorbell.num_pages; i++) {
+ if (rdev->doorbell.free[i]) {
+ rdev->doorbell.free[i] = false;
+ *doorbell = i;
+ return 0;
+ }
}
+ return -EINVAL;
}
/**
- * radeon_doorbell_free - Free a doorbell entry
+ * radeon_doorbell_free - Free a doorbell page
*
* @rdev: radeon_device pointer
- * @doorbell: doorbell index
+ * @doorbell: doorbell page number
*
- * Free a doorbell allocated for use by the driver (all asics)
+ * Free a doorbell page allocated for use by the driver (all asics)
*/
void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell)
{
- if (doorbell < rdev->doorbell.num_doorbells)
- __clear_bit(doorbell, rdev->doorbell.used);
+ if (doorbell < rdev->doorbell.num_pages)
+ rdev->doorbell.free[doorbell] = true;
}
/*
@@ -1076,10 +1076,7 @@ static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
{
struct drm_device *dev = pci_get_drvdata(pdev);
-
- if (radeon_is_px() && state == VGA_SWITCHEROO_OFF)
- return;
-
+ pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
if (state == VGA_SWITCHEROO_ON) {
unsigned d3_delay = dev->pdev->d3_delay;
@@ -1090,7 +1087,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev))
dev->pdev->d3_delay = 20;
- radeon_resume_kms(dev, true, true);
+ radeon_resume_kms(dev);
dev->pdev->d3_delay = d3_delay;
@@ -1100,7 +1097,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
printk(KERN_INFO "radeon: switched off\n");
drm_kms_helper_poll_disable(dev);
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
- radeon_suspend_kms(dev, true, true);
+ radeon_suspend_kms(dev, pmm);
dev->switch_power_state = DRM_SWITCH_POWER_OFF;
}
}
@@ -1150,7 +1147,6 @@ int radeon_device_init(struct radeon_device *rdev,
{
int r, i;
int dma_bits;
- bool runtime = false;
rdev->shutdown = false;
rdev->dev = &pdev->dev;
@@ -1297,14 +1293,7 @@ int radeon_device_init(struct radeon_device *rdev,
/* this will fail for cards that aren't VGA class devices, just
* ignore it */
vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
-
- if (radeon_runtime_pm == 1)
- runtime = true;
- if ((radeon_runtime_pm == -1) && radeon_is_px())
- runtime = true;
- vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
- if (runtime)
- vga_switcheroo_init_domain_pm_ops(rdev->dev, &rdev->vga_pm_domain);
+ vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, false);
r = radeon_init(rdev);
if (r)
@@ -1394,7 +1383,7 @@ void radeon_device_fini(struct radeon_device *rdev)
* Returns 0 for success or an error on failure.
* Called at driver suspend.
*/
-int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
+int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
{
struct radeon_device *rdev;
struct drm_crtc *crtc;
@@ -1405,7 +1394,9 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
if (dev == NULL || dev->dev_private == NULL) {
return -ENODEV;
}
-
+ if (state.event == PM_EVENT_PRETHAW) {
+ return 0;
+ }
rdev = dev->dev_private;
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
@@ -1464,17 +1455,14 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
radeon_agp_suspend(rdev);
pci_save_state(dev->pdev);
- if (suspend) {
+ if (state.event == PM_EVENT_SUSPEND) {
/* Shut down the device */
pci_disable_device(dev->pdev);
pci_set_power_state(dev->pdev, PCI_D3hot);
}
-
- if (fbcon) {
- console_lock();
- radeon_fbdev_set_suspend(rdev, 1);
- console_unlock();
- }
+ console_lock();
+ radeon_fbdev_set_suspend(rdev, 1);
+ console_unlock();
return 0;
}
@@ -1487,7 +1475,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
* Returns 0 for success or an error on failure.
* Called at driver resume.
*/
-int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
+int radeon_resume_kms(struct drm_device *dev)
{
struct drm_connector *connector;
struct radeon_device *rdev = dev->dev_private;
@@ -1496,17 +1484,12 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
- if (fbcon) {
- console_lock();
- }
- if (resume) {
- pci_set_power_state(dev->pdev, PCI_D0);
- pci_restore_state(dev->pdev);
- if (pci_enable_device(dev->pdev)) {
- if (fbcon)
- console_unlock();
- return -1;
- }
+ console_lock();
+ pci_set_power_state(dev->pdev, PCI_D0);
+ pci_restore_state(dev->pdev);
+ if (pci_enable_device(dev->pdev)) {
+ console_unlock();
+ return -1;
}
/* resume AGP if in use */
radeon_agp_resume(rdev);
@@ -1519,11 +1502,9 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
radeon_pm_resume(rdev);
radeon_restore_bios_scratch_regs(rdev);
- if (fbcon) {
- radeon_fbdev_set_suspend(rdev, 0);
- console_unlock();
- }
-
+ radeon_fbdev_set_suspend(rdev, 0);
+ console_unlock();
+
/* init dig PHYs, disp eng pll */
if (rdev->is_atom_bios) {
radeon_atom_encoder_init(rdev);
@@ -1568,14 +1549,6 @@ int radeon_gpu_reset(struct radeon_device *rdev)
int resched;
down_write(&rdev->exclusive_lock);
-
- if (!rdev->needs_reset) {
- up_write(&rdev->exclusive_lock);
- return 0;
- }
-
- rdev->needs_reset = false;
-
radeon_save_bios_scratch_regs(rdev);
/* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 7b25381..0d1aa05 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -30,7 +30,6 @@
#include "atom.h"
#include <asm/div64.h>
-#include <linux/pm_runtime.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
@@ -307,7 +306,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
*/
if (update_pending &&
(DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id,
- &vpos, &hpos, NULL, NULL)) &&
+ &vpos, &hpos)) &&
((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
(vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
/* crtc didn't flip in this target vblank interval,
@@ -495,55 +494,11 @@ unlock_free:
return r;
}
-static int
-radeon_crtc_set_config(struct drm_mode_set *set)
-{
- struct drm_device *dev;
- struct radeon_device *rdev;
- struct drm_crtc *crtc;
- bool active = false;
- int ret;
-
- if (!set || !set->crtc)
- return -EINVAL;
-
- dev = set->crtc->dev;
-
- ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0)
- return ret;
-
- ret = drm_crtc_helper_set_config(set);
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- if (crtc->enabled)
- active = true;
-
- pm_runtime_mark_last_busy(dev->dev);
-
- rdev = dev->dev_private;
- /* if we have active crtcs and we don't have a power ref,
- take the current one */
- if (active && !rdev->have_disp_power_ref) {
- rdev->have_disp_power_ref = true;
- return ret;
- }
- /* if we have no active crtcs, then drop the power ref
- we got before */
- if (!active && rdev->have_disp_power_ref) {
- pm_runtime_put_autosuspend(dev->dev);
- rdev->have_disp_power_ref = false;
- }
-
- /* drop the power reference we got coming in here */
- pm_runtime_put_autosuspend(dev->dev);
- return ret;
-}
static const struct drm_crtc_funcs radeon_crtc_funcs = {
.cursor_set = radeon_crtc_cursor_set,
.cursor_move = radeon_crtc_cursor_move,
.gamma_set = radeon_crtc_gamma_set,
- .set_config = radeon_crtc_set_config,
+ .set_config = drm_crtc_helper_set_config,
.destroy = radeon_crtc_destroy,
.page_flip = radeon_crtc_page_flip,
};
@@ -1223,12 +1178,6 @@ static struct drm_prop_enum_list radeon_audio_enum_list[] =
{ RADEON_AUDIO_AUTO, "auto" },
};
-/* XXX support different dither options? spatial, temporal, both, etc. */
-static struct drm_prop_enum_list radeon_dither_enum_list[] =
-{ { RADEON_FMT_DITHER_DISABLE, "off" },
- { RADEON_FMT_DITHER_ENABLE, "on" },
-};
-
static int radeon_modeset_create_props(struct radeon_device *rdev)
{
int sz;
@@ -1285,12 +1234,6 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
"audio",
radeon_audio_enum_list, sz);
- sz = ARRAY_SIZE(radeon_dither_enum_list);
- rdev->mode_info.dither_property =
- drm_property_create_enum(rdev->ddev, 0,
- "dither",
- radeon_dither_enum_list, sz);
-
return 0;
}
@@ -1596,17 +1539,12 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
}
/*
- * Retrieve current video scanout position of crtc on a given gpu, and
- * an optional accurate timestamp of when query happened.
+ * Retrieve current video scanout position of crtc on a given gpu.
*
* \param dev Device to query.
* \param crtc Crtc to query.
* \param *vpos Location where vertical scanout position should be stored.
* \param *hpos Location where horizontal scanout position should go.
- * \param *stime Target location for timestamp taken immediately before
- * scanout position query. Can be NULL to skip timestamp.
- * \param *etime Target location for timestamp taken immediately after
- * scanout position query. Can be NULL to skip timestamp.
*
* Returns vpos as a positive number while in active scanout area.
* Returns vpos as a negative number inside vblank, counting the number
@@ -1622,8 +1560,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
* unknown small number of scanlines wrt. real scanout position.
*
*/
-int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos,
- ktime_t *stime, ktime_t *etime)
+int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos)
{
u32 stat_crtc = 0, vbl = 0, position = 0;
int vbl_start, vbl_end, vtotal, ret = 0;
@@ -1631,12 +1568,6 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int
struct radeon_device *rdev = dev->dev_private;
- /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
-
- /* Get optional system timestamp before query. */
- if (stime)
- *stime = ktime_get();
-
if (ASIC_IS_DCE4(rdev)) {
if (crtc == 0) {
vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
@@ -1719,12 +1650,6 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int
}
}
- /* Get optional system timestamp after query. */
- if (etime)
- *etime = ktime_get();
-
- /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
-
/* Decode into vertical and horizontal scanout position. */
*vpos = position & 0x1fff;
*hpos = (position >> 16) & 0x1fff;
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 9f5ff28..9c14a1b 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -36,9 +36,8 @@
#include <drm/drm_pciids.h>
#include <linux/console.h>
#include <linux/module.h>
-#include <linux/pm_runtime.h>
-#include <linux/vga_switcheroo.h>
-#include "drm_crtc_helper.h"
+
+
/*
* KMS wrapper.
* - 2.0.0 - initial interface
@@ -76,10 +75,9 @@
* 2.32.0 - new info request for rings working
* 2.33.0 - Add SI tiling mode array query
* 2.34.0 - Add CIK tiling mode array query
- * 2.35.0 - Add CIK macrotile mode array query
*/
#define KMS_DRIVER_MAJOR 2
-#define KMS_DRIVER_MINOR 35
+#define KMS_DRIVER_MINOR 34
#define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev);
@@ -89,8 +87,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
struct drm_file *file_priv);
void radeon_driver_preclose_kms(struct drm_device *dev,
struct drm_file *file_priv);
-int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon);
-int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
+int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
+int radeon_resume_kms(struct drm_device *dev);
u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc);
int radeon_enable_vblank_kms(struct drm_device *dev, int crtc);
void radeon_disable_vblank_kms(struct drm_device *dev, int crtc);
@@ -102,14 +100,14 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev);
int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS);
+int radeon_gem_object_init(struct drm_gem_object *obj);
void radeon_gem_object_free(struct drm_gem_object *obj);
int radeon_gem_object_open(struct drm_gem_object *obj,
struct drm_file *file_priv);
void radeon_gem_object_close(struct drm_gem_object *obj,
struct drm_file *file_priv);
extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
- int *vpos, int *hpos, ktime_t *stime,
- ktime_t *etime);
+ int *vpos, int *hpos);
extern const struct drm_ioctl_desc radeon_ioctls_kms[];
extern int radeon_max_kms_ioctl;
int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -139,11 +137,9 @@ void radeon_debugfs_cleanup(struct drm_minor *minor);
#if defined(CONFIG_VGA_SWITCHEROO)
void radeon_register_atpx_handler(void);
void radeon_unregister_atpx_handler(void);
-bool radeon_is_px(void);
#else
static inline void radeon_register_atpx_handler(void) {}
static inline void radeon_unregister_atpx_handler(void) {}
-static inline bool radeon_is_px(void) { return false; }
#endif
int radeon_no_wb;
@@ -166,7 +162,6 @@ int radeon_lockup_timeout = 10000;
int radeon_fastfb = 0;
int radeon_dpm = -1;
int radeon_aspm = -1;
-int radeon_runtime_pm = -1;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -228,9 +223,6 @@ module_param_named(dpm, radeon_dpm, int, 0444);
MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)");
module_param_named(aspm, radeon_aspm, int, 0444);
-MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)");
-module_param_named(runpm, radeon_runtime_pm, int, 0444);
-
static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
};
@@ -267,7 +259,6 @@ static int radeon_resume(struct drm_device *dev)
return 0;
}
-
static const struct file_operations radeon_driver_old_fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -362,144 +353,25 @@ radeon_pci_remove(struct pci_dev *pdev)
drm_put_dev(dev);
}
-static int radeon_pmops_suspend(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
- return radeon_suspend_kms(drm_dev, true, true);
-}
-
-static int radeon_pmops_resume(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
- return radeon_resume_kms(drm_dev, true, true);
-}
-
-static int radeon_pmops_freeze(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
- return radeon_suspend_kms(drm_dev, false, true);
-}
-
-static int radeon_pmops_thaw(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
- return radeon_resume_kms(drm_dev, false, true);
-}
-
-static int radeon_pmops_runtime_suspend(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
- int ret;
-
- if (radeon_runtime_pm == 0)
- return -EINVAL;
-
- drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
- drm_kms_helper_poll_disable(drm_dev);
- vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
-
- ret = radeon_suspend_kms(drm_dev, false, false);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3cold);
- drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
-
- return 0;
-}
-
-static int radeon_pmops_runtime_resume(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
- int ret;
-
- if (radeon_runtime_pm == 0)
- return -EINVAL;
-
- drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_set_master(pdev);
-
- ret = radeon_resume_kms(drm_dev, false, false);
- drm_kms_helper_poll_enable(drm_dev);
- vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
- drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
- return 0;
-}
-
-static int radeon_pmops_runtime_idle(struct device *dev)
+static int
+radeon_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
- struct drm_crtc *crtc;
-
- if (radeon_runtime_pm == 0)
- return -EBUSY;
-
- /* are we PX enabled? */
- if (radeon_runtime_pm == -1 && !radeon_is_px()) {
- DRM_DEBUG_DRIVER("failing to power off - not px\n");
- return -EBUSY;
- }
-
- list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
- if (crtc->enabled) {
- DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
- return -EBUSY;
- }
- }
-
- pm_runtime_mark_last_busy(dev);
- pm_runtime_autosuspend(dev);
- /* we don't want the main rpm_idle to call suspend - we want to autosuspend */
- return 1;
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ return radeon_suspend_kms(dev, state);
}
-long radeon_drm_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int
+radeon_pci_resume(struct pci_dev *pdev)
{
- struct drm_file *file_priv = filp->private_data;
- struct drm_device *dev;
- long ret;
- dev = file_priv->minor->dev;
- ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0)
- return ret;
-
- ret = drm_ioctl(filp, cmd, arg);
-
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
- return ret;
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ return radeon_resume_kms(dev);
}
-static const struct dev_pm_ops radeon_pm_ops = {
- .suspend = radeon_pmops_suspend,
- .resume = radeon_pmops_resume,
- .freeze = radeon_pmops_freeze,
- .thaw = radeon_pmops_thaw,
- .poweroff = radeon_pmops_freeze,
- .restore = radeon_pmops_resume,
- .runtime_suspend = radeon_pmops_runtime_suspend,
- .runtime_resume = radeon_pmops_runtime_resume,
- .runtime_idle = radeon_pmops_runtime_idle,
-};
-
static const struct file_operations radeon_driver_kms_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.release = drm_release,
- .unlocked_ioctl = radeon_drm_ioctl,
+ .unlocked_ioctl = drm_ioctl,
.mmap = radeon_mmap,
.poll = drm_poll,
.read = drm_read,
@@ -508,15 +380,6 @@ static const struct file_operations radeon_driver_kms_fops = {
#endif
};
-
-static void
-radeon_pci_shutdown(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
-
- radeon_driver_unload_kms(dev);
-}
-
static struct drm_driver kms_driver = {
.driver_features =
DRIVER_USE_AGP |
@@ -529,6 +392,8 @@ static struct drm_driver kms_driver = {
.postclose = radeon_driver_postclose_kms,
.lastclose = radeon_driver_lastclose_kms,
.unload = radeon_driver_unload_kms,
+ .suspend = radeon_suspend_kms,
+ .resume = radeon_resume_kms,
.get_vblank_counter = radeon_get_vblank_counter_kms,
.enable_vblank = radeon_enable_vblank_kms,
.disable_vblank = radeon_disable_vblank_kms,
@@ -543,6 +408,7 @@ static struct drm_driver kms_driver = {
.irq_uninstall = radeon_driver_irq_uninstall_kms,
.irq_handler = radeon_driver_irq_handler_kms,
.ioctls = radeon_ioctls_kms,
+ .gem_init_object = radeon_gem_object_init,
.gem_free_object = radeon_gem_object_free,
.gem_open_object = radeon_gem_object_open,
.gem_close_object = radeon_gem_object_close,
@@ -585,8 +451,8 @@ static struct pci_driver radeon_kms_pci_driver = {
.id_table = pciidlist,
.probe = radeon_pci_probe,
.remove = radeon_pci_remove,
- .driver.pm = &radeon_pm_ops,
- .shutdown = radeon_pci_shutdown,
+ .suspend = radeon_pci_suspend,
+ .resume = radeon_pci_resume,
};
static int __init radeon_init(void)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 00e0d44..b369d42 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -108,15 +108,11 @@
* 1.31- Add support for num Z pipes from GET_PARAM
* 1.32- fixes for rv740 setup
* 1.33- Add r6xx/r7xx const buffer support
- * 1.34- fix evergreen/cayman GS register
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 34
+#define DRIVER_MINOR 33
#define DRIVER_PATCHLEVEL 0
-long radeon_drm_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg);
-
/* The rest of the file is DEPRECATED! */
#ifdef CONFIG_DRM_RADEON_UMS
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h
index 614ad54..3c82890 100644
--- a/drivers/gpu/drm/radeon/radeon_family.h
+++ b/drivers/gpu/drm/radeon/radeon_family.h
@@ -96,7 +96,6 @@ enum radeon_family {
CHIP_BONAIRE,
CHIP_KAVERI,
CHIP_KABINI,
- CHIP_HAWAII,
CHIP_LAST,
};
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index d3a86e4..ddb8f8e 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -190,8 +190,10 @@ void radeon_fence_process(struct radeon_device *rdev, int ring)
}
} while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq);
- if (wake)
+ if (wake) {
+ rdev->fence_drv[ring].last_activity = jiffies;
wake_up_all(&rdev->fence_queue);
+ }
}
/**
@@ -210,13 +212,13 @@ static void radeon_fence_destroy(struct kref *kref)
}
/**
- * radeon_fence_seq_signaled - check if a fence sequence number has signaled
+ * radeon_fence_seq_signaled - check if a fence sequeuce number has signaled
*
* @rdev: radeon device pointer
* @seq: sequence number
* @ring: ring index the fence is associated with
*
- * Check if the last signaled fence sequnce number is >= the requested
+ * Check if the last singled fence sequnce number is >= the requested
* sequence number (all asics).
* Returns true if the fence has signaled (current fence value
* is >= requested value) or false if it has not (current fence
@@ -261,131 +263,113 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
}
/**
- * radeon_fence_any_seq_signaled - check if any sequence number is signaled
+ * radeon_fence_wait_seq - wait for a specific sequence number
*
* @rdev: radeon device pointer
- * @seq: sequence numbers
- *
- * Check if the last signaled fence sequnce number is >= the requested
- * sequence number (all asics).
- * Returns true if any has signaled (current value is >= requested value)
- * or false if it has not. Helper function for radeon_fence_wait_seq.
- */
-static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
-{
- unsigned i;
-
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i))
- return true;
- }
- return false;
-}
-
-/**
- * radeon_fence_wait_seq - wait for a specific sequence numbers
- *
- * @rdev: radeon device pointer
- * @target_seq: sequence number(s) we want to wait for
+ * @target_seq: sequence number we want to wait for
+ * @ring: ring index the fence is associated with
* @intr: use interruptable sleep
* @lock_ring: whether the ring should be locked or not
*
- * Wait for the requested sequence number(s) to be written by any ring
- * (all asics). Sequnce number array is indexed by ring id.
+ * Wait for the requested sequence number to be written (all asics).
* @intr selects whether to use interruptable (true) or non-interruptable
* (false) sleep when waiting for the sequence number. Helper function
- * for radeon_fence_wait_*().
+ * for radeon_fence_wait(), et al.
* Returns 0 if the sequence number has passed, error for all other cases.
- * -EDEADLK is returned when a GPU lockup has been detected.
+ * -EDEADLK is returned when a GPU lockup has been detected and the ring is
+ * marked as not ready so no further jobs get scheduled until a successful
+ * reset.
*/
-static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 *target_seq,
- bool intr, bool lock_ring)
+static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq,
+ unsigned ring, bool intr, bool lock_ring)
{
- uint64_t last_seq[RADEON_NUM_RINGS];
+ unsigned long timeout, last_activity;
+ uint64_t seq;
+ unsigned i;
bool signaled;
- int i, r;
-
- while (!radeon_fence_any_seq_signaled(rdev, target_seq)) {
-
- /* Save current sequence values, used to check for GPU lockups */
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- if (!target_seq[i])
- continue;
+ int r;
- last_seq[i] = atomic64_read(&rdev->fence_drv[i].last_seq);
- trace_radeon_fence_wait_begin(rdev->ddev, target_seq[i]);
- radeon_irq_kms_sw_irq_get(rdev, i);
+ while (target_seq > atomic64_read(&rdev->fence_drv[ring].last_seq)) {
+ if (!rdev->ring[ring].ready) {
+ return -EBUSY;
}
- if (intr) {
- r = wait_event_interruptible_timeout(rdev->fence_queue, (
- (signaled = radeon_fence_any_seq_signaled(rdev, target_seq))
- || rdev->needs_reset), RADEON_FENCE_JIFFIES_TIMEOUT);
+ timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT;
+ if (time_after(rdev->fence_drv[ring].last_activity, timeout)) {
+ /* the normal case, timeout is somewhere before last_activity */
+ timeout = rdev->fence_drv[ring].last_activity - timeout;
} else {
- r = wait_event_timeout(rdev->fence_queue, (
- (signaled = radeon_fence_any_seq_signaled(rdev, target_seq))
- || rdev->needs_reset), RADEON_FENCE_JIFFIES_TIMEOUT);
+ /* either jiffies wrapped around, or no fence was signaled in the last 500ms
+ * anyway we will just wait for the minimum amount and then check for a lockup
+ */
+ timeout = 1;
}
+ seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
+ /* Save current last activity valuee, used to check for GPU lockups */
+ last_activity = rdev->fence_drv[ring].last_activity;
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- if (!target_seq[i])
- continue;
-
- radeon_irq_kms_sw_irq_put(rdev, i);
- trace_radeon_fence_wait_end(rdev->ddev, target_seq[i]);
+ trace_radeon_fence_wait_begin(rdev->ddev, seq);
+ radeon_irq_kms_sw_irq_get(rdev, ring);
+ if (intr) {
+ r = wait_event_interruptible_timeout(rdev->fence_queue,
+ (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)),
+ timeout);
+ } else {
+ r = wait_event_timeout(rdev->fence_queue,
+ (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)),
+ timeout);
}
-
- if (unlikely(r < 0))
+ radeon_irq_kms_sw_irq_put(rdev, ring);
+ if (unlikely(r < 0)) {
return r;
+ }
+ trace_radeon_fence_wait_end(rdev->ddev, seq);
if (unlikely(!signaled)) {
- if (rdev->needs_reset)
- return -EDEADLK;
-
/* we were interrupted for some reason and fence
* isn't signaled yet, resume waiting */
- if (r)
+ if (r) {
continue;
-
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- if (!target_seq[i])
- continue;
-
- if (last_seq[i] != atomic64_read(&rdev->fence_drv[i].last_seq))
- break;
}
- if (i != RADEON_NUM_RINGS)
+ /* check if sequence value has changed since last_activity */
+ if (seq != atomic64_read(&rdev->fence_drv[ring].last_seq)) {
continue;
+ }
- if (lock_ring)
+ if (lock_ring) {
mutex_lock(&rdev->ring_lock);
+ }
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- if (!target_seq[i])
- continue;
-
- if (radeon_ring_is_lockup(rdev, i, &rdev->ring[i]))
- break;
+ /* test if somebody else has already decided that this is a lockup */
+ if (last_activity != rdev->fence_drv[ring].last_activity) {
+ if (lock_ring) {
+ mutex_unlock(&rdev->ring_lock);
+ }
+ continue;
}
- if (i < RADEON_NUM_RINGS) {
+ if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) {
/* good news we believe it's a lockup */
- dev_warn(rdev->dev, "GPU lockup (waiting for "
- "0x%016llx last fence id 0x%016llx on"
- " ring %d)\n",
- target_seq[i], last_seq[i], i);
-
- /* remember that we need an reset */
- rdev->needs_reset = true;
- if (lock_ring)
+ dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx last fence id 0x%016llx)\n",
+ target_seq, seq);
+
+ /* change last activity so nobody else think there is a lockup */
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ rdev->fence_drv[i].last_activity = jiffies;
+ }
+
+ /* mark the ring as not ready any more */
+ rdev->ring[ring].ready = false;
+ if (lock_ring) {
mutex_unlock(&rdev->ring_lock);
- wake_up_all(&rdev->fence_queue);
+ }
return -EDEADLK;
}
- if (lock_ring)
+ if (lock_ring) {
mutex_unlock(&rdev->ring_lock);
+ }
}
}
return 0;
@@ -404,7 +388,6 @@ static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 *target_seq,
*/
int radeon_fence_wait(struct radeon_fence *fence, bool intr)
{
- uint64_t seq[RADEON_NUM_RINGS] = {};
int r;
if (fence == NULL) {
@@ -412,18 +395,150 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
return -EINVAL;
}
- seq[fence->ring] = fence->seq;
- if (seq[fence->ring] == RADEON_FENCE_SIGNALED_SEQ)
- return 0;
-
- r = radeon_fence_wait_seq(fence->rdev, seq, intr, true);
- if (r)
+ r = radeon_fence_wait_seq(fence->rdev, fence->seq,
+ fence->ring, intr, true);
+ if (r) {
return r;
-
+ }
fence->seq = RADEON_FENCE_SIGNALED_SEQ;
return 0;
}
+static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
+{
+ unsigned i;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * radeon_fence_wait_any_seq - wait for a sequence number on any ring
+ *
+ * @rdev: radeon device pointer
+ * @target_seq: sequence number(s) we want to wait for
+ * @intr: use interruptable sleep
+ *
+ * Wait for the requested sequence number(s) to be written by any ring
+ * (all asics). Sequnce number array is indexed by ring id.
+ * @intr selects whether to use interruptable (true) or non-interruptable
+ * (false) sleep when waiting for the sequence number. Helper function
+ * for radeon_fence_wait_any(), et al.
+ * Returns 0 if the sequence number has passed, error for all other cases.
+ */
+static int radeon_fence_wait_any_seq(struct radeon_device *rdev,
+ u64 *target_seq, bool intr)
+{
+ unsigned long timeout, last_activity, tmp;
+ unsigned i, ring = RADEON_NUM_RINGS;
+ bool signaled;
+ int r;
+
+ for (i = 0, last_activity = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (!target_seq[i]) {
+ continue;
+ }
+
+ /* use the most recent one as indicator */
+ if (time_after(rdev->fence_drv[i].last_activity, last_activity)) {
+ last_activity = rdev->fence_drv[i].last_activity;
+ }
+
+ /* For lockup detection just pick the lowest ring we are
+ * actively waiting for
+ */
+ if (i < ring) {
+ ring = i;
+ }
+ }
+
+ /* nothing to wait for ? */
+ if (ring == RADEON_NUM_RINGS) {
+ return -ENOENT;
+ }
+
+ while (!radeon_fence_any_seq_signaled(rdev, target_seq)) {
+ timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT;
+ if (time_after(last_activity, timeout)) {
+ /* the normal case, timeout is somewhere before last_activity */
+ timeout = last_activity - timeout;
+ } else {
+ /* either jiffies wrapped around, or no fence was signaled in the last 500ms
+ * anyway we will just wait for the minimum amount and then check for a lockup
+ */
+ timeout = 1;
+ }
+
+ trace_radeon_fence_wait_begin(rdev->ddev, target_seq[ring]);
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (target_seq[i]) {
+ radeon_irq_kms_sw_irq_get(rdev, i);
+ }
+ }
+ if (intr) {
+ r = wait_event_interruptible_timeout(rdev->fence_queue,
+ (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)),
+ timeout);
+ } else {
+ r = wait_event_timeout(rdev->fence_queue,
+ (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)),
+ timeout);
+ }
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (target_seq[i]) {
+ radeon_irq_kms_sw_irq_put(rdev, i);
+ }
+ }
+ if (unlikely(r < 0)) {
+ return r;
+ }
+ trace_radeon_fence_wait_end(rdev->ddev, target_seq[ring]);
+
+ if (unlikely(!signaled)) {
+ /* we were interrupted for some reason and fence
+ * isn't signaled yet, resume waiting */
+ if (r) {
+ continue;
+ }
+
+ mutex_lock(&rdev->ring_lock);
+ for (i = 0, tmp = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (time_after(rdev->fence_drv[i].last_activity, tmp)) {
+ tmp = rdev->fence_drv[i].last_activity;
+ }
+ }
+ /* test if somebody else has already decided that this is a lockup */
+ if (last_activity != tmp) {
+ last_activity = tmp;
+ mutex_unlock(&rdev->ring_lock);
+ continue;
+ }
+
+ if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) {
+ /* good news we believe it's a lockup */
+ dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx)\n",
+ target_seq[ring]);
+
+ /* change last activity so nobody else think there is a lockup */
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ rdev->fence_drv[i].last_activity = jiffies;
+ }
+
+ /* mark the ring as not ready any more */
+ rdev->ring[ring].ready = false;
+ mutex_unlock(&rdev->ring_lock);
+ return -EDEADLK;
+ }
+ mutex_unlock(&rdev->ring_lock);
+ }
+ }
+ return 0;
+}
+
/**
* radeon_fence_wait_any - wait for a fence to signal on any ring
*
@@ -442,7 +557,7 @@ int radeon_fence_wait_any(struct radeon_device *rdev,
bool intr)
{
uint64_t seq[RADEON_NUM_RINGS];
- unsigned i, num_rings = 0;
+ unsigned i;
int r;
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
@@ -452,19 +567,15 @@ int radeon_fence_wait_any(struct radeon_device *rdev,
continue;
}
- seq[i] = fences[i]->seq;
- ++num_rings;
-
- /* test if something was allready signaled */
- if (seq[i] == RADEON_FENCE_SIGNALED_SEQ)
+ if (fences[i]->seq == RADEON_FENCE_SIGNALED_SEQ) {
+ /* something was allready signaled */
return 0;
- }
+ }
- /* nothing to wait for ? */
- if (num_rings == 0)
- return -ENOENT;
+ seq[i] = fences[i]->seq;
+ }
- r = radeon_fence_wait_seq(rdev, seq, intr, true);
+ r = radeon_fence_wait_any_seq(rdev, seq, intr);
if (r) {
return r;
}
@@ -472,36 +583,6 @@ int radeon_fence_wait_any(struct radeon_device *rdev,
}
/**
- * radeon_fence_wait_locked - wait for a fence to signal
- *
- * @fence: radeon fence object
- *
- * Wait for the requested fence to signal (all asics).
- * Returns 0 if the fence has passed, error for all other cases.
- */
-int radeon_fence_wait_locked(struct radeon_fence *fence)
-{
- uint64_t seq[RADEON_NUM_RINGS] = {};
- int r;
-
- if (fence == NULL) {
- WARN(1, "Querying an invalid fence : %p !\n", fence);
- return -EINVAL;
- }
-
- seq[fence->ring] = fence->seq;
- if (seq[fence->ring] == RADEON_FENCE_SIGNALED_SEQ)
- return 0;
-
- r = radeon_fence_wait_seq(fence->rdev, seq, false, false);
- if (r)
- return r;
-
- fence->seq = RADEON_FENCE_SIGNALED_SEQ;
- return 0;
-}
-
-/**
* radeon_fence_wait_next_locked - wait for the next fence to signal
*
* @rdev: radeon device pointer
@@ -513,15 +594,15 @@ int radeon_fence_wait_locked(struct radeon_fence *fence)
*/
int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring)
{
- uint64_t seq[RADEON_NUM_RINGS] = {};
+ uint64_t seq;
- seq[ring] = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL;
- if (seq[ring] >= rdev->fence_drv[ring].sync_seq[ring]) {
+ seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL;
+ if (seq >= rdev->fence_drv[ring].sync_seq[ring]) {
/* nothing to wait for, last_seq is
already the last emited fence */
return -ENOENT;
}
- return radeon_fence_wait_seq(rdev, seq, false, false);
+ return radeon_fence_wait_seq(rdev, seq, ring, false, false);
}
/**
@@ -536,18 +617,14 @@ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring)
*/
int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
{
- uint64_t seq[RADEON_NUM_RINGS] = {};
+ uint64_t seq = rdev->fence_drv[ring].sync_seq[ring];
int r;
- seq[ring] = rdev->fence_drv[ring].sync_seq[ring];
- if (!seq[ring])
- return 0;
-
- r = radeon_fence_wait_seq(rdev, seq, false, false);
+ r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
if (r) {
- if (r == -EDEADLK)
+ if (r == -EDEADLK) {
return -EDEADLK;
-
+ }
dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%d)\n",
ring, r);
}
@@ -749,6 +826,7 @@ static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring)
for (i = 0; i < RADEON_NUM_RINGS; ++i)
rdev->fence_drv[ring].sync_seq[i] = 0;
atomic64_set(&rdev->fence_drv[ring].last_seq, 0);
+ rdev->fence_drv[ring].last_activity = jiffies;
rdev->fence_drv[ring].initialized = false;
}
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 96e4400..b990b1a 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -29,7 +29,6 @@
#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_reg.h"
-#include "radeon_trace.h"
/*
* GART
@@ -608,8 +607,8 @@ static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm)
*/
int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm)
{
- unsigned pd_size, pd_entries, pts_size;
- struct radeon_ib ib;
+ unsigned pd_size, pts_size;
+ u64 *pd_addr;
int r;
if (vm == NULL) {
@@ -620,10 +619,8 @@ int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm)
return 0;
}
- pd_size = radeon_vm_directory_size(rdev);
- pd_entries = radeon_vm_num_pdes(rdev);
-
retry:
+ pd_size = radeon_vm_directory_size(rdev);
r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager,
&vm->page_directory, pd_size,
RADEON_VM_PTB_ALIGN_SIZE, false);
@@ -640,31 +637,9 @@ retry:
vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->page_directory);
/* Initially clear the page directory */
- r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib,
- NULL, pd_entries * 2 + 64);
- if (r) {
- radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence);
- return r;
- }
-
- ib.length_dw = 0;
-
- radeon_asic_vm_set_page(rdev, &ib, vm->pd_gpu_addr,
- 0, pd_entries, 0, 0);
-
- radeon_semaphore_sync_to(ib.semaphore, vm->fence);
- r = radeon_ib_schedule(rdev, &ib, NULL);
- if (r) {
- radeon_ib_free(rdev, &ib);
- radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence);
- return r;
- }
- radeon_fence_unref(&vm->fence);
- vm->fence = radeon_fence_ref(ib.fence);
- radeon_ib_free(rdev, &ib);
- radeon_fence_unref(&vm->last_flush);
+ pd_addr = radeon_sa_bo_cpu_addr(vm->page_directory);
+ memset(pd_addr, 0, pd_size);
- /* allocate page table array */
pts_size = radeon_vm_num_pdes(rdev) * sizeof(struct radeon_sa_bo *);
vm->page_tables = kzalloc(pts_size, GFP_KERNEL);
@@ -738,7 +713,6 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
for (i = 0; i < 2; ++i) {
if (choices[i]) {
vm->id = choices[i];
- trace_radeon_vm_grab_id(vm->id, ring);
return rdev->vm_manager.active[choices[i]];
}
}
@@ -940,26 +914,6 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr)
}
/**
- * radeon_vm_page_flags - translate page flags to what the hw uses
- *
- * @flags: flags comming from userspace
- *
- * Translate the flags the userspace ABI uses to hw flags.
- */
-static uint32_t radeon_vm_page_flags(uint32_t flags)
-{
- uint32_t hw_flags = 0;
- hw_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0;
- hw_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0;
- hw_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0;
- if (flags & RADEON_VM_PAGE_SYSTEM) {
- hw_flags |= R600_PTE_SYSTEM;
- hw_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0;
- }
- return hw_flags;
-}
-
-/**
* radeon_vm_update_pdes - make sure that page directory is valid
*
* @rdev: radeon_device pointer
@@ -1020,11 +974,7 @@ retry:
if (count) {
radeon_asic_vm_set_page(rdev, ib, last_pde,
last_pt, count, incr,
- R600_PTE_VALID);
-
- count *= RADEON_VM_PTE_COUNT;
- radeon_asic_vm_set_page(rdev, ib, last_pt, 0,
- count, 0, 0);
+ RADEON_VM_PAGE_VALID);
}
count = 1;
@@ -1037,11 +987,8 @@ retry:
if (count) {
radeon_asic_vm_set_page(rdev, ib, last_pde, last_pt, count,
- incr, R600_PTE_VALID);
+ incr, RADEON_VM_PAGE_VALID);
- count *= RADEON_VM_PTE_COUNT;
- radeon_asic_vm_set_page(rdev, ib, last_pt, 0,
- count, 0, 0);
}
return 0;
@@ -1118,7 +1065,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
}
/**
- * radeon_vm_bo_update - map a bo into the vm page table
+ * radeon_vm_bo_update_pte - map a bo into the vm page table
*
* @rdev: radeon_device pointer
* @vm: requested vm
@@ -1130,11 +1077,12 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
*
* Object have to be reserved & global and local mutex must be locked!
*/
-int radeon_vm_bo_update(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo,
- struct ttm_mem_reg *mem)
+int radeon_vm_bo_update_pte(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_bo *bo,
+ struct ttm_mem_reg *mem)
{
+ unsigned ridx = rdev->asic->vm.pt_ring_index;
struct radeon_ib ib;
struct radeon_bo_va *bo_va;
unsigned nptes, npdes, ndw;
@@ -1178,8 +1126,6 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
bo_va->valid = false;
}
- trace_radeon_vm_bo_update(bo_va);
-
nptes = radeon_bo_ngpu_pages(bo);
/* assume two extra pdes in case the mapping overlaps the borders */
@@ -1205,16 +1151,11 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
/* reserve space for pde addresses */
ndw += npdes * 2;
- /* reserve space for clearing new page tables */
- ndw += npdes * 2 * RADEON_VM_PTE_COUNT;
-
/* update too big for an IB */
if (ndw > 0xfffff)
return -ENOMEM;
- r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, ndw * 4);
- if (r)
- return r;
+ r = radeon_ib_get(rdev, ridx, &ib, NULL, ndw * 4);
ib.length_dw = 0;
r = radeon_vm_update_pdes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset);
@@ -1224,9 +1165,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
}
radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset,
- addr, radeon_vm_page_flags(bo_va->flags));
+ addr, bo_va->flags);
- radeon_semaphore_sync_to(ib.semaphore, vm->fence);
+ radeon_ib_sync_to(&ib, vm->fence);
r = radeon_ib_schedule(rdev, &ib, NULL);
if (r) {
radeon_ib_free(rdev, &ib);
@@ -1261,7 +1202,7 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
mutex_lock(&rdev->vm_manager.lock);
mutex_lock(&bo_va->vm->mutex);
if (bo_va->soffset) {
- r = radeon_vm_bo_update(rdev, bo_va->vm, bo_va->bo, NULL);
+ r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL);
}
mutex_unlock(&rdev->vm_manager.lock);
list_del(&bo_va->vm_list);
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 805c5e5..dce99c8 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -29,6 +29,13 @@
#include <drm/radeon_drm.h>
#include "radeon.h"
+int radeon_gem_object_init(struct drm_gem_object *obj)
+{
+ BUG();
+
+ return 0;
+}
+
void radeon_gem_object_free(struct drm_gem_object *gobj)
{
struct radeon_bo *robj = gem_to_radeon_bo(gobj);
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c
index bdb0f93..c180df8 100644
--- a/drivers/gpu/drm/radeon/radeon_ioc32.c
+++ b/drivers/gpu/drm/radeon/radeon_ioc32.c
@@ -418,7 +418,7 @@ long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long
if (nr < DRM_COMMAND_BASE)
return drm_compat_ioctl(filp, cmd, arg);
- ret = radeon_drm_ioctl(filp, cmd, arg);
+ ret = drm_ioctl(filp, cmd, arg);
return ret;
}
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index ec6240b..cc9e848 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -32,8 +32,6 @@
#include "radeon.h"
#include "atom.h"
-#include <linux/pm_runtime.h>
-
#define RADEON_WAIT_IDLE_TIMEOUT 200
/**
@@ -49,12 +47,8 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
struct radeon_device *rdev = dev->dev_private;
- irqreturn_t ret;
- ret = radeon_irq_process(rdev);
- if (ret == IRQ_HANDLED)
- pm_runtime_mark_last_busy(dev->dev);
- return ret;
+ return radeon_irq_process(rdev);
}
/*
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 55d0b47..61580dd 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -32,7 +32,7 @@
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
-#include <linux/pm_runtime.h>
+
/**
* radeon_driver_unload_kms - Main unload function for KMS.
*
@@ -50,14 +50,9 @@ int radeon_driver_unload_kms(struct drm_device *dev)
if (rdev == NULL)
return 0;
-
if (rdev->rmmio == NULL)
goto done_free;
-
- pm_runtime_get_sync(dev->dev);
-
radeon_acpi_fini(rdev);
-
radeon_modeset_fini(rdev);
radeon_device_fini(rdev);
@@ -130,20 +125,9 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
"Error during ACPI methods call\n");
}
- if (radeon_runtime_pm != 0) {
- pm_runtime_use_autosuspend(dev->dev);
- pm_runtime_set_autosuspend_delay(dev->dev, 5000);
- pm_runtime_set_active(dev->dev);
- pm_runtime_allow(dev->dev);
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
- }
-
out:
if (r)
radeon_driver_unload_kms(dev);
-
-
return r;
}
@@ -207,7 +191,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
switch (info->request) {
case RADEON_INFO_DEVICE_ID:
- *value = dev->pdev->device;
+ *value = dev->pci_device;
break;
case RADEON_INFO_NUM_GB_PIPES:
*value = rdev->num_gb_pipes;
@@ -340,7 +324,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
break;
case RADEON_INFO_BACKEND_MAP:
if (rdev->family >= CHIP_BONAIRE)
- *value = rdev->config.cik.backend_map;
+ return -EINVAL;
else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.backend_map;
else if (rdev->family >= CHIP_CAYMAN)
@@ -449,15 +433,6 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
return -EINVAL;
}
break;
- case RADEON_INFO_CIK_MACROTILE_MODE_ARRAY:
- if (rdev->family >= CHIP_BONAIRE) {
- value = rdev->config.cik.macrotile_mode_array;
- value_size = sizeof(uint32_t)*16;
- } else {
- DRM_DEBUG_KMS("macrotile mode array is cik+ only!\n");
- return -EINVAL;
- }
- break;
case RADEON_INFO_SI_CP_DMA_COMPUTE:
*value = 1;
break;
@@ -500,14 +475,9 @@ void radeon_driver_lastclose_kms(struct drm_device *dev)
int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
{
struct radeon_device *rdev = dev->dev_private;
- int r;
file_priv->driver_priv = NULL;
- r = pm_runtime_get_sync(dev->dev);
- if (r < 0)
- return r;
-
/* new gpu have virtual address space support */
if (rdev->family >= CHIP_CAYMAN) {
struct radeon_fpriv *fpriv;
@@ -536,9 +506,6 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
file_priv->driver_priv = fpriv;
}
-
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 0b158f9..7cb178a 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -422,7 +422,6 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc,
/* Pin framebuffer & get tilling informations */
obj = radeon_fb->obj;
rbo = gem_to_radeon_bo(obj);
-retry:
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
@@ -431,33 +430,6 @@ retry:
&base);
if (unlikely(r != 0)) {
radeon_bo_unreserve(rbo);
-
- /* On old GPU like RN50 with little vram pining can fails because
- * current fb is taking all space needed. So instead of unpining
- * the old buffer after pining the new one, first unpin old one
- * and then retry pining new one.
- *
- * As only master can set mode only master can pin and it is
- * unlikely the master client will race with itself especialy
- * on those old gpu with single crtc.
- *
- * We don't shutdown the display controller because new buffer
- * will end up in same spot.
- */
- if (!atomic && fb && fb != crtc->fb) {
- struct radeon_bo *old_rbo;
- unsigned long nsize, osize;
-
- old_rbo = gem_to_radeon_bo(to_radeon_framebuffer(fb)->obj);
- osize = radeon_bo_size(old_rbo);
- nsize = radeon_bo_size(rbo);
- if (nsize <= osize && !radeon_bo_reserve(old_rbo, false)) {
- radeon_bo_unpin(old_rbo);
- radeon_bo_unreserve(old_rbo);
- fb = NULL;
- goto retry;
- }
- }
return -EINVAL;
}
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
@@ -1084,26 +1056,6 @@ static void radeon_crtc_commit(struct drm_crtc *crtc)
}
}
-static void radeon_crtc_disable(struct drm_crtc *crtc)
-{
- radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
- if (crtc->fb) {
- int r;
- struct radeon_framebuffer *radeon_fb;
- struct radeon_bo *rbo;
-
- radeon_fb = to_radeon_framebuffer(crtc->fb);
- rbo = gem_to_radeon_bo(radeon_fb->obj);
- r = radeon_bo_reserve(rbo, false);
- if (unlikely(r))
- DRM_ERROR("failed to reserve rbo before unpin\n");
- else {
- radeon_bo_unpin(rbo);
- radeon_bo_unreserve(rbo);
- }
- }
-}
-
static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.dpms = radeon_crtc_dpms,
.mode_fixup = radeon_crtc_mode_fixup,
@@ -1113,7 +1065,6 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.prepare = radeon_crtc_prepare,
.commit = radeon_crtc_commit,
.load_lut = radeon_crtc_load_lut,
- .disable = radeon_crtc_disable
};
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index c89971d..62cd512 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -392,7 +392,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
props.type = BACKLIGHT_RAW;
snprintf(bl_name, sizeof(bl_name),
"radeon_bl%d", dev->primary->index);
- bd = backlight_device_register(bl_name, drm_connector->kdev,
+ bd = backlight_device_register(bl_name, &drm_connector->kdev,
pdata, &radeon_backlight_ops, &props);
if (IS_ERR(bd)) {
DRM_ERROR("Backlight registration failed\n");
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 3f0dd66..ef63d3f 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -249,8 +249,6 @@ struct radeon_mode_info {
struct drm_property *underscan_vborder_property;
/* audio */
struct drm_property *audio_property;
- /* FMT dithering */
- struct drm_property *dither_property;
/* hardcoded DFP edid from BIOS */
struct edid *bios_hardcoded_edid;
int bios_hardcoded_edid_size;
@@ -481,11 +479,6 @@ enum radeon_connector_audio {
RADEON_AUDIO_AUTO = 2
};
-enum radeon_connector_dither {
- RADEON_FMT_DITHER_DISABLE = 0,
- RADEON_FMT_DITHER_ENABLE = 1,
-};
-
struct radeon_connector {
struct drm_connector base;
uint32_t connector_id;
@@ -505,7 +498,6 @@ struct radeon_connector {
struct radeon_router router;
struct radeon_i2c_chan *router_bus;
enum radeon_connector_audio audio;
- enum radeon_connector_dither dither;
};
struct radeon_framebuffer {
@@ -766,8 +758,7 @@ extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
int x, int y);
extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
- int *vpos, int *hpos, ktime_t *stime,
- ktime_t *etime);
+ int *vpos, int *hpos);
extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev);
extern struct edid *
@@ -859,12 +850,6 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
-/* fmt blocks */
-void avivo_program_fmt(struct drm_encoder *encoder);
-void dce3_program_fmt(struct drm_encoder *encoder);
-void dce4_program_fmt(struct drm_encoder *encoder);
-void dce8_program_fmt(struct drm_encoder *encoder);
-
/* fbdev layer */
int radeon_fbdev_init(struct radeon_device *rdev);
void radeon_fbdev_fini(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index dc75bb6..4f6b7fc 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -508,21 +508,17 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev,
} else if (strncmp("auto", buf, strlen("auto")) == 0) {
level = RADEON_DPM_FORCED_LEVEL_AUTO;
} else {
+ mutex_unlock(&rdev->pm.mutex);
count = -EINVAL;
goto fail;
}
if (rdev->asic->dpm.force_performance_level) {
- if (rdev->pm.dpm.thermal_active) {
- count = -EINVAL;
- goto fail;
- }
ret = radeon_dpm_force_performance_level(rdev, level);
if (ret)
count = -EINVAL;
}
-fail:
mutex_unlock(&rdev->pm.mutex);
-
+fail:
return count;
}
@@ -537,7 +533,8 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct radeon_device *rdev = dev_get_drvdata(dev);
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct radeon_device *rdev = ddev->dev_private;
int temp;
if (rdev->asic->pm.get_temperature)
@@ -565,14 +562,23 @@ static ssize_t radeon_hwmon_show_temp_thresh(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", temp);
}
+static ssize_t radeon_hwmon_show_name(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "radeon\n");
+}
+
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 1);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0);
static struct attribute *hwmon_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
+ &sensor_dev_attr_name.dev_attr.attr,
NULL
};
@@ -597,15 +603,11 @@ static const struct attribute_group hwmon_attrgroup = {
.is_visible = hwmon_attributes_visible,
};
-static const struct attribute_group *hwmon_groups[] = {
- &hwmon_attrgroup,
- NULL
-};
-
static int radeon_hwmon_init(struct radeon_device *rdev)
{
int err = 0;
- struct device *hwmon_dev;
+
+ rdev->pm.int_hwmon_dev = NULL;
switch (rdev->pm.int_thermal_type) {
case THERMAL_TYPE_RV6XX:
@@ -618,13 +620,20 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
case THERMAL_TYPE_KV:
if (rdev->asic->pm.get_temperature == NULL)
return err;
- hwmon_dev = hwmon_device_register_with_groups(rdev->dev,
- "radeon", rdev,
- hwmon_groups);
- if (IS_ERR(hwmon_dev)) {
- err = PTR_ERR(hwmon_dev);
+ rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
+ if (IS_ERR(rdev->pm.int_hwmon_dev)) {
+ err = PTR_ERR(rdev->pm.int_hwmon_dev);
dev_err(rdev->dev,
"Unable to register hwmon device: %d\n", err);
+ break;
+ }
+ dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev);
+ err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj,
+ &hwmon_attrgroup);
+ if (err) {
+ dev_err(rdev->dev,
+ "Unable to create hwmon sysfs file: %d\n", err);
+ hwmon_device_unregister(rdev->dev);
}
break;
default:
@@ -634,6 +643,14 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
return err;
}
+static void radeon_hwmon_fini(struct radeon_device *rdev)
+{
+ if (rdev->pm.int_hwmon_dev) {
+ sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup);
+ hwmon_device_unregister(rdev->pm.int_hwmon_dev);
+ }
+}
+
static void radeon_dpm_thermal_work_handler(struct work_struct *work)
{
struct radeon_device *rdev =
@@ -864,12 +881,11 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
}
}
- if (radeon_dpm == 1) {
- printk("switching from power state:\n");
- radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps);
- printk("switching to power state:\n");
- radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps);
- }
+ printk("switching from power state:\n");
+ radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps);
+ printk("switching to power state:\n");
+ radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps);
+
mutex_lock(&rdev->ddev->struct_mutex);
down_write(&rdev->pm.mclk_lock);
mutex_lock(&rdev->ring_lock);
@@ -902,16 +918,12 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
radeon_dpm_post_set_power_state(rdev);
if (rdev->asic->dpm.force_performance_level) {
- if (rdev->pm.dpm.thermal_active) {
- enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;
+ if (rdev->pm.dpm.thermal_active)
/* force low perf level for thermal */
radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_LOW);
- /* save the user's level */
- rdev->pm.dpm.forced_level = level;
- } else {
- /* otherwise, user selected level */
- radeon_dpm_force_performance_level(rdev, rdev->pm.dpm.forced_level);
- }
+ else
+ /* otherwise, enable auto */
+ radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO);
}
done:
@@ -1167,8 +1179,7 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
mutex_lock(&rdev->pm.mutex);
radeon_dpm_init(rdev);
rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps;
- if (radeon_dpm == 1)
- radeon_dpm_print_power_states(rdev);
+ radeon_dpm_print_power_states(rdev);
radeon_dpm_setup_asic(rdev);
ret = radeon_dpm_enable(rdev);
mutex_unlock(&rdev->pm.mutex);
@@ -1230,23 +1241,6 @@ int radeon_pm_init(struct radeon_device *rdev)
case CHIP_RV670:
case CHIP_RS780:
case CHIP_RS880:
- case CHIP_CAYMAN:
- case CHIP_BONAIRE:
- case CHIP_KABINI:
- case CHIP_KAVERI:
- case CHIP_HAWAII:
- /* DPM requires the RLC, RV770+ dGPU requires SMC */
- if (!rdev->rlc_fw)
- rdev->pm.pm_method = PM_METHOD_PROFILE;
- else if ((rdev->family >= CHIP_RV770) &&
- (!(rdev->flags & RADEON_IS_IGP)) &&
- (!rdev->smc_fw))
- rdev->pm.pm_method = PM_METHOD_PROFILE;
- else if (radeon_dpm == 1)
- rdev->pm.pm_method = PM_METHOD_DPM;
- else
- rdev->pm.pm_method = PM_METHOD_PROFILE;
- break;
case CHIP_RV770:
case CHIP_RV730:
case CHIP_RV710:
@@ -1262,12 +1256,16 @@ int radeon_pm_init(struct radeon_device *rdev)
case CHIP_BARTS:
case CHIP_TURKS:
case CHIP_CAICOS:
+ case CHIP_CAYMAN:
case CHIP_ARUBA:
case CHIP_TAHITI:
case CHIP_PITCAIRN:
case CHIP_VERDE:
case CHIP_OLAND:
case CHIP_HAINAN:
+ case CHIP_BONAIRE:
+ case CHIP_KABINI:
+ case CHIP_KAVERI:
/* DPM requires the RLC, RV770+ dGPU requires SMC */
if (!rdev->rlc_fw)
rdev->pm.pm_method = PM_METHOD_PROFILE;
@@ -1275,10 +1273,10 @@ int radeon_pm_init(struct radeon_device *rdev)
(!(rdev->flags & RADEON_IS_IGP)) &&
(!rdev->smc_fw))
rdev->pm.pm_method = PM_METHOD_PROFILE;
- else if (radeon_dpm == 0)
- rdev->pm.pm_method = PM_METHOD_PROFILE;
- else
+ else if (radeon_dpm == 1)
rdev->pm.pm_method = PM_METHOD_DPM;
+ else
+ rdev->pm.pm_method = PM_METHOD_PROFILE;
break;
default:
/* default to profile method */
@@ -1316,6 +1314,8 @@ static void radeon_pm_fini_old(struct radeon_device *rdev)
if (rdev->pm.power_state)
kfree(rdev->pm.power_state);
+
+ radeon_hwmon_fini(rdev);
}
static void radeon_pm_fini_dpm(struct radeon_device *rdev)
@@ -1335,6 +1335,8 @@ static void radeon_pm_fini_dpm(struct radeon_device *rdev)
if (rdev->pm.power_state)
kfree(rdev->pm.power_state);
+
+ radeon_hwmon_fini(rdev);
}
void radeon_pm_fini(struct radeon_device *rdev)
@@ -1466,7 +1468,7 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev)
*/
for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) {
if (rdev->pm.active_crtcs & (1 << crtc)) {
- vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos, NULL, NULL);
+ vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos);
if ((vbl_status & DRM_SCANOUTPOS_VALID) &&
!(vbl_status & DRM_SCANOUTPOS_INVBL))
in_vbl = false;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 9214403..18254e1 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -61,7 +61,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
struct radeon_ib *ib, struct radeon_vm *vm,
unsigned size)
{
- int r;
+ int i, r;
r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true);
if (r) {
@@ -87,6 +87,8 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
}
ib->is_const_ib = false;
+ for (i = 0; i < RADEON_NUM_RINGS; ++i)
+ ib->sync_to[i] = NULL;
return 0;
}
@@ -107,6 +109,25 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
}
/**
+ * radeon_ib_sync_to - sync to fence before executing the IB
+ *
+ * @ib: IB object to add fence to
+ * @fence: fence to sync to
+ *
+ * Sync to the fence before executing the IB
+ */
+void radeon_ib_sync_to(struct radeon_ib *ib, struct radeon_fence *fence)
+{
+ struct radeon_fence *other;
+
+ if (!fence)
+ return;
+
+ other = ib->sync_to[fence->ring];
+ ib->sync_to[fence->ring] = radeon_fence_later(fence, other);
+}
+
+/**
* radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring
*
* @rdev: radeon_device pointer
@@ -130,7 +151,8 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
struct radeon_ib *const_ib)
{
struct radeon_ring *ring = &rdev->ring[ib->ring];
- int r = 0;
+ bool need_sync = false;
+ int i, r = 0;
if (!ib->length_dw || !ring->ready) {
/* TODO: Nothings in the ib we should report. */
@@ -144,15 +166,19 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
dev_err(rdev->dev, "scheduling IB failed (%d).\n", r);
return r;
}
-
- /* sync with other rings */
- r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring);
- if (r) {
- dev_err(rdev->dev, "failed to sync rings (%d)\n", r);
- radeon_ring_unlock_undo(rdev, ring);
- return r;
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ struct radeon_fence *fence = ib->sync_to[i];
+ if (radeon_fence_need_sync(fence, ib->ring)) {
+ need_sync = true;
+ radeon_semaphore_sync_rings(rdev, ib->semaphore,
+ fence->ring, ib->ring);
+ radeon_fence_note_sync(fence, ib->ring);
+ }
+ }
+ /* immediately free semaphore when we don't need to sync */
+ if (!need_sync) {
+ radeon_semaphore_free(rdev, &ib->semaphore, NULL);
}
-
/* if we can't remember our last VM flush then flush now! */
/* XXX figure out why we have to flush for every IB */
if (ib->vm /*&& !ib->vm->last_flush*/) {
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 2b42aa1..8dcc20f 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -29,12 +29,12 @@
*/
#include <drm/drmP.h>
#include "radeon.h"
-#include "radeon_trace.h"
+
int radeon_semaphore_create(struct radeon_device *rdev,
struct radeon_semaphore **semaphore)
{
- int i, r;
+ int r;
*semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL);
if (*semaphore == NULL) {
@@ -50,121 +50,54 @@ int radeon_semaphore_create(struct radeon_device *rdev,
(*semaphore)->waiters = 0;
(*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo);
*((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0;
-
- for (i = 0; i < RADEON_NUM_RINGS; ++i)
- (*semaphore)->sync_to[i] = NULL;
-
return 0;
}
-bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ridx,
+void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore)
{
- struct radeon_ring *ring = &rdev->ring[ridx];
-
- trace_radeon_semaphore_signale(ridx, semaphore);
-
- if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, false)) {
- --semaphore->waiters;
-
- /* for debugging lockup only, used by sysfs debug files */
- ring->last_semaphore_signal_addr = semaphore->gpu_addr;
- return true;
- }
- return false;
+ --semaphore->waiters;
+ radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false);
}
-bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx,
+void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
struct radeon_semaphore *semaphore)
{
- struct radeon_ring *ring = &rdev->ring[ridx];
-
- trace_radeon_semaphore_wait(ridx, semaphore);
-
- if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, true)) {
- ++semaphore->waiters;
-
- /* for debugging lockup only, used by sysfs debug files */
- ring->last_semaphore_wait_addr = semaphore->gpu_addr;
- return true;
- }
- return false;
-}
-
-/**
- * radeon_semaphore_sync_to - use the semaphore to sync to a fence
- *
- * @semaphore: semaphore object to add fence to
- * @fence: fence to sync to
- *
- * Sync to the fence using this semaphore object
- */
-void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore,
- struct radeon_fence *fence)
-{
- struct radeon_fence *other;
-
- if (!fence)
- return;
-
- other = semaphore->sync_to[fence->ring];
- semaphore->sync_to[fence->ring] = radeon_fence_later(fence, other);
+ ++semaphore->waiters;
+ radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true);
}
-/**
- * radeon_semaphore_sync_rings - sync ring to all registered fences
- *
- * @rdev: radeon_device pointer
- * @semaphore: semaphore object to use for sync
- * @ring: ring that needs sync
- *
- * Ensure that all registered fences are signaled before letting
- * the ring continue. The caller must hold the ring lock.
- */
+/* caller must hold ring lock */
int radeon_semaphore_sync_rings(struct radeon_device *rdev,
struct radeon_semaphore *semaphore,
- int ring)
+ int signaler, int waiter)
{
- int i, r;
-
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- struct radeon_fence *fence = semaphore->sync_to[i];
+ int r;
- /* check if we really need to sync */
- if (!radeon_fence_need_sync(fence, ring))
- continue;
-
- /* prevent GPU deadlocks */
- if (!rdev->ring[i].ready) {
- dev_err(rdev->dev, "Syncing to a disabled ring!");
- return -EINVAL;
- }
+ /* no need to signal and wait on the same ring */
+ if (signaler == waiter) {
+ return 0;
+ }
- /* allocate enough space for sync command */
- r = radeon_ring_alloc(rdev, &rdev->ring[i], 16);
- if (r) {
- return r;
- }
+ /* prevent GPU deadlocks */
+ if (!rdev->ring[signaler].ready) {
+ dev_err(rdev->dev, "Trying to sync to a disabled ring!");
+ return -EINVAL;
+ }
- /* emit the signal semaphore */
- if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) {
- /* signaling wasn't successful wait manually */
- radeon_ring_undo(&rdev->ring[i]);
- radeon_fence_wait_locked(fence);
- continue;
- }
+ r = radeon_ring_alloc(rdev, &rdev->ring[signaler], 8);
+ if (r) {
+ return r;
+ }
+ radeon_semaphore_emit_signal(rdev, signaler, semaphore);
+ radeon_ring_commit(rdev, &rdev->ring[signaler]);
- /* we assume caller has already allocated space on waiters ring */
- if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) {
- /* waiting wasn't successful wait manually */
- radeon_ring_undo(&rdev->ring[i]);
- radeon_fence_wait_locked(fence);
- continue;
- }
+ /* we assume caller has already allocated space on waiters ring */
+ radeon_semaphore_emit_wait(rdev, waiter, semaphore);
- radeon_ring_commit(rdev, &rdev->ring[i]);
- radeon_fence_note_sync(fence, ring);
- }
+ /* for debugging lockup only, used by sysfs debug files */
+ rdev->ring[signaler].last_semaphore_signal_addr = semaphore->gpu_addr;
+ rdev->ring[waiter].last_semaphore_wait_addr = semaphore->gpu_addr;
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h
index 0473257..f7e3678 100644
--- a/drivers/gpu/drm/radeon/radeon_trace.h
+++ b/drivers/gpu/drm/radeon/radeon_trace.h
@@ -47,63 +47,6 @@ TRACE_EVENT(radeon_cs,
__entry->fences)
);
-TRACE_EVENT(radeon_vm_grab_id,
- TP_PROTO(unsigned vmid, int ring),
- TP_ARGS(vmid, ring),
- TP_STRUCT__entry(
- __field(u32, vmid)
- __field(u32, ring)
- ),
-
- TP_fast_assign(
- __entry->vmid = vmid;
- __entry->ring = ring;
- ),
- TP_printk("vmid=%u, ring=%u", __entry->vmid, __entry->ring)
-);
-
-TRACE_EVENT(radeon_vm_bo_update,
- TP_PROTO(struct radeon_bo_va *bo_va),
- TP_ARGS(bo_va),
- TP_STRUCT__entry(
- __field(u64, soffset)
- __field(u64, eoffset)
- __field(u32, flags)
- ),
-
- TP_fast_assign(
- __entry->soffset = bo_va->soffset;
- __entry->eoffset = bo_va->eoffset;
- __entry->flags = bo_va->flags;
- ),
- TP_printk("soffs=%010llx, eoffs=%010llx, flags=%08x",
- __entry->soffset, __entry->eoffset, __entry->flags)
-);
-
-TRACE_EVENT(radeon_vm_set_page,
- TP_PROTO(uint64_t pe, uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags),
- TP_ARGS(pe, addr, count, incr, flags),
- TP_STRUCT__entry(
- __field(u64, pe)
- __field(u64, addr)
- __field(u32, count)
- __field(u32, incr)
- __field(u32, flags)
- ),
-
- TP_fast_assign(
- __entry->pe = pe;
- __entry->addr = addr;
- __entry->count = count;
- __entry->incr = incr;
- __entry->flags = flags;
- ),
- TP_printk("pe=%010Lx, addr=%010Lx, incr=%u, flags=%08x, count=%u",
- __entry->pe, __entry->addr, __entry->incr,
- __entry->flags, __entry->count)
-);
-
DECLARE_EVENT_CLASS(radeon_fence_request,
TP_PROTO(struct drm_device *dev, u32 seqno),
@@ -144,42 +87,6 @@ DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_end,
TP_ARGS(dev, seqno)
);
-DECLARE_EVENT_CLASS(radeon_semaphore_request,
-
- TP_PROTO(int ring, struct radeon_semaphore *sem),
-
- TP_ARGS(ring, sem),
-
- TP_STRUCT__entry(
- __field(int, ring)
- __field(signed, waiters)
- __field(uint64_t, gpu_addr)
- ),
-
- TP_fast_assign(
- __entry->ring = ring;
- __entry->waiters = sem->waiters;
- __entry->gpu_addr = sem->gpu_addr;
- ),
-
- TP_printk("ring=%u, waiters=%d, addr=%010Lx", __entry->ring,
- __entry->waiters, __entry->gpu_addr)
-);
-
-DEFINE_EVENT(radeon_semaphore_request, radeon_semaphore_signale,
-
- TP_PROTO(int ring, struct radeon_semaphore *sem),
-
- TP_ARGS(ring, sem)
-);
-
-DEFINE_EVENT(radeon_semaphore_request, radeon_semaphore_wait,
-
- TP_PROTO(int ring, struct radeon_semaphore *sem),
-
- TP_ARGS(ring, sem)
-);
-
#endif
/* This part must be outside protection */
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h
index a77cd27..3385836 100644
--- a/drivers/gpu/drm/radeon/radeon_ucode.h
+++ b/drivers/gpu/drm/radeon/radeon_ucode.h
@@ -59,7 +59,6 @@
#define SI_MC_UCODE_SIZE 7769
#define OLAND_MC_UCODE_SIZE 7863
#define CIK_MC_UCODE_SIZE 7866
-#define HAWAII_MC_UCODE_SIZE 7933
/* SDMA */
#define CIK_SDMA_UCODE_SIZE 1050
@@ -144,7 +143,4 @@
#define BONAIRE_SMC_UCODE_START 0x20000
#define BONAIRE_SMC_UCODE_SIZE 0x1FDEC
-#define HAWAII_SMC_UCODE_START 0x20000
-#define HAWAII_SMC_UCODE_SIZE 0x1FDEC
-
#endif
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c
index 373d088..308eff5 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -97,7 +97,6 @@ int radeon_uvd_init(struct radeon_device *rdev)
case CHIP_BONAIRE:
case CHIP_KABINI:
case CHIP_KAVERI:
- case CHIP_HAWAII:
fw_name = FIRMWARE_BONAIRE;
break;
@@ -241,8 +240,6 @@ void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp)
if (handle != 0 && rdev->uvd.filp[i] == filp) {
struct radeon_fence *fence;
- radeon_uvd_note_usage(rdev);
-
r = radeon_uvd_get_destroy_msg(rdev,
R600_RING_TYPE_UVD_INDEX, handle, &fence);
if (r) {
@@ -623,7 +620,7 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev,
if (r)
goto err;
- r = radeon_ib_get(rdev, ring, &ib, NULL, 64);
+ r = radeon_ib_get(rdev, ring, &ib, NULL, 16);
if (r)
goto err;
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman
index d46b58d..a072fa8 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/cayman
+++ b/drivers/gpu/drm/radeon/reg_srcs/cayman
@@ -21,7 +21,7 @@ cayman 0x9400
0x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE
0x000089B0 VGT_HS_OFFCHIP_PARAM
0x00008A14 PA_CL_ENHANCE
-0x00008A60 PA_SU_LINE_STIPPLE_VALUE
+0x00008A60 PA_SC_LINE_STIPPLE_VALUE
0x00008B10 PA_SC_LINE_STIPPLE_STATE
0x00008BF0 PA_SC_ENHANCE
0x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
@@ -532,7 +532,7 @@ cayman 0x9400
0x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET
0x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE
0x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET
-0x00028B90 VGT_GS_INSTANCE_CNT
+0x00028B74 VGT_GS_INSTANCE_CNT
0x00028BD4 PA_SC_CENTROID_PRIORITY_0
0x00028BD8 PA_SC_CENTROID_PRIORITY_1
0x00028BDC PA_SC_LINE_CNTL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
index 57745c8..b912a37 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/evergreen
+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen
@@ -22,7 +22,7 @@ evergreen 0x9400
0x000089A4 VGT_COMPUTE_START_Z
0x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE
0x00008A14 PA_CL_ENHANCE
-0x00008A60 PA_SU_LINE_STIPPLE_VALUE
+0x00008A60 PA_SC_LINE_STIPPLE_VALUE
0x00008B10 PA_SC_LINE_STIPPLE_STATE
0x00008BF0 PA_SC_ENHANCE
0x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
@@ -545,7 +545,7 @@ evergreen 0x9400
0x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET
0x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE
0x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET
-0x00028B90 VGT_GS_INSTANCE_CNT
+0x00028B74 VGT_GS_INSTANCE_CNT
0x00028C00 PA_SC_LINE_CNTL
0x00028C08 PA_SU_VTX_CNTL
0x00028C0C PA_CL_GB_VERT_CLIP_ADJ
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 76cc8d3..6acba80 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -153,70 +153,6 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING;
}
-void avivo_program_fmt(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
- int bpc = 0;
- u32 tmp = 0;
- enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
-
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- bpc = radeon_get_monitor_bpc(connector);
- dither = radeon_connector->dither;
- }
-
- /* LVDS FMT is set up by atom */
- if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
- return;
-
- if (bpc == 0)
- return;
-
- switch (bpc) {
- case 6:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;
- else
- tmp |= AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN;
- break;
- case 8:
- if (dither == RADEON_FMT_DITHER_ENABLE)
- /* XXX sort out optimal dither settings */
- tmp |= (AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN |
- AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH);
- else
- tmp |= (AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN |
- AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH);
- break;
- case 10:
- default:
- /* not needed */
- break;
- }
-
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
- WREG32(AVIVO_TMDSA_BIT_DEPTH_CONTROL, tmp);
- break;
- case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
- WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, tmp);
- break;
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
- WREG32(AVIVO_DVOA_BIT_DEPTH_CONTROL, tmp);
- break;
- case ENCODER_OBJECT_ID_INTERNAL_DDI:
- WREG32(AVIVO_DDIA_BIT_DEPTH_CONTROL, tmp);
- break;
- default:
- break;
- }
-}
-
void rs600_pm_misc(struct radeon_device *rdev)
{
int requested_index = rdev->pm.requested_power_state_index;
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 1c56062..1447d79 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -345,11 +345,9 @@ static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
if (max_bandwidth.full > rdev->pm.sideport_bandwidth.full &&
rdev->pm.sideport_bandwidth.full)
max_bandwidth = rdev->pm.sideport_bandwidth;
- read_delay_latency.full = dfixed_const(370 * 800);
- a.full = dfixed_const(1000);
- b.full = dfixed_div(rdev->pm.igp_sideport_mclk, a);
- read_delay_latency.full = dfixed_div(read_delay_latency, b);
- read_delay_latency.full = dfixed_mul(read_delay_latency, a);
+ read_delay_latency.full = dfixed_const(370 * 800 * 1000);
+ read_delay_latency.full = dfixed_div(read_delay_latency,
+ rdev->pm.igp_sideport_mclk);
} else {
if (max_bandwidth.full > rdev->pm.k8_bandwidth.full &&
rdev->pm.k8_bandwidth.full)
@@ -490,10 +488,14 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev,
}
if (wm0->priority_mark.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark.full;
+ if (dfixed_trunc(priority_mark02) < 0)
+ priority_mark02.full = 0;
if (wm0->priority_mark_max.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark_max.full;
if (wm1->priority_mark.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark.full;
+ if (dfixed_trunc(priority_mark12) < 0)
+ priority_mark12.full = 0;
if (wm1->priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark_max.full;
*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
@@ -524,6 +526,8 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev,
}
if (wm0->priority_mark.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark.full;
+ if (dfixed_trunc(priority_mark02) < 0)
+ priority_mark02.full = 0;
if (wm0->priority_mark_max.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark_max.full;
*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
@@ -551,6 +555,8 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev,
}
if (wm1->priority_mark.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark.full;
+ if (dfixed_trunc(priority_mark12) < 0)
+ priority_mark12.full = 0;
if (wm1->priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark_max.full;
*d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 5d1c316..873eb4b 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -1155,10 +1155,14 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev,
}
if (wm0->priority_mark.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark.full;
+ if (dfixed_trunc(priority_mark02) < 0)
+ priority_mark02.full = 0;
if (wm0->priority_mark_max.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark_max.full;
if (wm1->priority_mark.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark.full;
+ if (dfixed_trunc(priority_mark12) < 0)
+ priority_mark12.full = 0;
if (wm1->priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark_max.full;
*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
@@ -1189,6 +1193,8 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev,
}
if (wm0->priority_mark.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark.full;
+ if (dfixed_trunc(priority_mark02) < 0)
+ priority_mark02.full = 0;
if (wm0->priority_mark_max.full > priority_mark02.full)
priority_mark02.full = wm0->priority_mark_max.full;
*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
@@ -1216,6 +1222,8 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev,
}
if (wm1->priority_mark.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark.full;
+ if (dfixed_trunc(priority_mark12) < 0)
+ priority_mark12.full = 0;
if (wm1->priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1->priority_mark_max.full;
*d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c
index 26633a0..5811d27 100644
--- a/drivers/gpu/drm/radeon/rv6xx_dpm.c
+++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c
@@ -407,9 +407,9 @@ static void rv6xx_enable_engine_feedback_and_reference_sync(struct radeon_device
WREG32_P(SPLL_CNTL_MODE, SPLL_DIV_SYNC, ~SPLL_DIV_SYNC);
}
-static u32 rv6xx_clocks_per_unit(u32 unit)
+static u64 rv6xx_clocks_per_unit(u32 unit)
{
- u32 tmp = 1 << (2 * unit);
+ u64 tmp = 1 << (2 * unit);
return tmp;
}
@@ -417,7 +417,7 @@ static u32 rv6xx_clocks_per_unit(u32 unit)
static u32 rv6xx_scale_count_given_unit(struct radeon_device *rdev,
u32 unscaled_count, u32 unit)
{
- u32 count_per_unit = rv6xx_clocks_per_unit(unit);
+ u32 count_per_unit = (u32)rv6xx_clocks_per_unit(unit);
return (unscaled_count + count_per_unit - 1) / count_per_unit;
}
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c
index aca8cbe..f9b02e3 100644
--- a/drivers/gpu/drm/radeon/rv770_dma.c
+++ b/drivers/gpu/drm/radeon/rv770_dma.c
@@ -66,8 +66,13 @@ int rv770_copy_dma(struct radeon_device *rdev,
return r;
}
- radeon_semaphore_sync_to(sem, *fence);
- radeon_semaphore_sync_rings(rdev, sem, ring->idx);
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
for (i = 0; i < num_loops; i++) {
cur_size_in_dw = size_in_dw;
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index a36736d..d96f7cb 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -78,6 +78,11 @@ extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_
extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev);
extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
extern bool evergreen_is_display_hung(struct radeon_device *rdev);
+extern void si_dma_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
bool enable);
static void si_fini_pg(struct radeon_device *rdev);
@@ -3882,15 +3887,8 @@ static int si_mc_init(struct radeon_device *rdev)
rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
/* size in MB on si */
- tmp = RREG32(CONFIG_MEMSIZE);
- /* some boards may have garbage in the upper 16 bits */
- if (tmp & 0xffff0000) {
- DRM_INFO("Probable bad vram size: 0x%08x\n", tmp);
- if (tmp & 0xffff)
- tmp &= 0xffff;
- }
- rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL;
- rdev->mc.real_vram_size = rdev->mc.mc_vram_size;
+ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+ rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
rdev->mc.visible_vram_size = rdev->mc.aper_size;
si_vram_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev);
@@ -4675,6 +4673,61 @@ static void si_vm_decode_fault(struct radeon_device *rdev,
block, mc_id);
}
+/**
+ * si_vm_set_page - update the page tables using the CP
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using the CP (SI).
+ */
+void si_vm_set_page(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+ uint64_t value;
+ unsigned ndw;
+
+ if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
+ while (count) {
+ ndw = 2 + count * 2;
+ if (ndw > 0x3FFE)
+ ndw = 0x3FFE;
+
+ ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw);
+ ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(1));
+ ib->ptr[ib->length_dw++] = pe;
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+ for (; ndw > 2; ndw -= 2, --count, pe += 8) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
+ addr += incr;
+ value |= r600_flags;
+ ib->ptr[ib->length_dw++] = value;
+ ib->ptr[ib->length_dw++] = upper_32_bits(value);
+ }
+ }
+ } else {
+ /* DMA */
+ si_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags);
+ }
+}
+
void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
{
struct radeon_ring *ring = &rdev->ring[ridx];
@@ -5319,53 +5372,52 @@ void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
if (buffer == NULL)
return;
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
- buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
+ buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0);
+ buffer[count++] = PACKET3_PREAMBLE_BEGIN_CLEAR_STATE;
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
- buffer[count++] = cpu_to_le32(0x80000000);
- buffer[count++] = cpu_to_le32(0x80000000);
+ buffer[count++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1);
+ buffer[count++] = 0x80000000;
+ buffer[count++] = 0x80000000;
for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
for (ext = sect->section; ext->extent != NULL; ++ext) {
if (sect->id == SECT_CONTEXT) {
- buffer[count++] =
- cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
- buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);
+ buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count);
+ buffer[count++] = ext->reg_index - 0xa000;
for (i = 0; i < ext->reg_count; i++)
- buffer[count++] = cpu_to_le32(ext->extent[i]);
+ buffer[count++] = ext->extent[i];
} else {
return;
}
}
}
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1));
- buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
+ buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ buffer[count++] = PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START;
switch (rdev->family) {
case CHIP_TAHITI:
case CHIP_PITCAIRN:
- buffer[count++] = cpu_to_le32(0x2a00126a);
+ buffer[count++] = 0x2a00126a;
break;
case CHIP_VERDE:
- buffer[count++] = cpu_to_le32(0x0000124a);
+ buffer[count++] = 0x0000124a;
break;
case CHIP_OLAND:
- buffer[count++] = cpu_to_le32(0x00000082);
+ buffer[count++] = 0x00000082;
break;
case CHIP_HAINAN:
- buffer[count++] = cpu_to_le32(0x00000000);
+ buffer[count++] = 0x00000000;
break;
default:
- buffer[count++] = cpu_to_le32(0x00000000);
+ buffer[count++] = 0x00000000;
break;
}
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
- buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
+ buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0);
+ buffer[count++] = PACKET3_PREAMBLE_END_CLEAR_STATE;
- buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
- buffer[count++] = cpu_to_le32(0);
+ buffer[count++] = PACKET3(PACKET3_CLEAR_STATE, 0);
+ buffer[count++] = 0;
}
static void si_init_pg(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index 59be2cf..49909d2 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -24,7 +24,6 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_trace.h"
#include "sid.h"
u32 si_gpu_check_soft_reset(struct radeon_device *rdev);
@@ -76,12 +75,11 @@ void si_dma_vm_set_page(struct radeon_device *rdev,
uint64_t addr, unsigned count,
uint32_t incr, uint32_t flags)
{
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
uint64_t value;
unsigned ndw;
- trace_radeon_vm_set_page(pe, addr, count, incr, flags);
-
- if (flags & R600_PTE_SYSTEM) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
while (count) {
ndw = count * 2;
if (ndw > 0xFFFFE)
@@ -92,10 +90,16 @@ void si_dma_vm_set_page(struct radeon_device *rdev,
ib->ptr[ib->length_dw++] = pe;
ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
for (; ndw > 0; ndw -= 2, --count, pe += 8) {
- value = radeon_vm_map_gart(rdev, addr);
- value &= 0xFFFFFFFFFFFFF000ULL;
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
addr += incr;
- value |= flags;
+ value |= r600_flags;
ib->ptr[ib->length_dw++] = value;
ib->ptr[ib->length_dw++] = upper_32_bits(value);
}
@@ -106,7 +110,7 @@ void si_dma_vm_set_page(struct radeon_device *rdev,
if (ndw > 0xFFFFE)
ndw = 0xFFFFE;
- if (flags & R600_PTE_VALID)
+ if (flags & RADEON_VM_PAGE_VALID)
value = addr;
else
value = 0;
@@ -114,7 +118,7 @@ void si_dma_vm_set_page(struct radeon_device *rdev,
ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
ib->ptr[ib->length_dw++] = pe; /* dst addr */
ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
- ib->ptr[ib->length_dw++] = flags; /* mask */
+ ib->ptr[ib->length_dw++] = r600_flags; /* mask */
ib->ptr[ib->length_dw++] = 0;
ib->ptr[ib->length_dw++] = value; /* value */
ib->ptr[ib->length_dw++] = upper_32_bits(value);
@@ -195,8 +199,13 @@ int si_copy_dma(struct radeon_device *rdev,
return r;
}
- radeon_semaphore_sync_to(sem, *fence);
- radeon_semaphore_sync_rings(rdev, sem, ring->idx);
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
for (i = 0; i < num_loops; i++) {
cur_size_in_bytes = size_in_bytes;
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 0b00c79..2332aa1 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -3589,12 +3589,7 @@ static void si_program_display_gap(struct radeon_device *rdev)
WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);
}
- /* Setting this to false forces the performance state to low if the crtcs are disabled.
- * This can be a problem on PowerXpress systems or if you want to use the card
- * for offscreen rendering or compute if there are no crtcs enabled. Set it to
- * true for now so that performance scales even if the displays are off.
- */
- si_notify_smc_display_change(rdev, true /*rdev->pm.dpm.new_active_crtc_count > 0*/);
+ si_notify_smc_display_change(rdev, rdev->pm.dpm.new_active_crtc_count > 0);
}
static void si_enable_spread_spectrum(struct radeon_device *rdev, bool enable)
@@ -4558,7 +4553,7 @@ static int si_init_smc_table(struct radeon_device *rdev)
table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY)
- table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;
+ table->systemFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) {
table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO;
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index b322acc..7e2e0ea 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -478,7 +478,7 @@
#define STATE3_MASK (0x1f << 15)
#define STATE3_SHIFT 15
-#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x28e8
+#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x2808
#define TRAIN_DONE_D0 (1 << 30)
#define TRAIN_DONE_D1 (1 << 31)
@@ -683,51 +683,6 @@
* bit5 = 176.4 kHz
* bit6 = 192 kHz
*/
-
-#define AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x37
-# define VIDEO_LIPSYNC(x) (((x) & 0xff) << 0)
-# define AUDIO_LIPSYNC(x) (((x) & 0xff) << 8)
-/* VIDEO_LIPSYNC, AUDIO_LIPSYNC
- * 0 = invalid
- * x = legal delay value
- * 255 = sync not supported
- */
-#define AZ_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x38
-# define HBR_CAPABLE (1 << 0) /* enabled by default */
-
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x3a
-# define MANUFACTURER_ID(x) (((x) & 0xffff) << 0)
-# define PRODUCT_ID(x) (((x) & 0xffff) << 16)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x3b
-# define SINK_DESCRIPTION_LEN(x) (((x) & 0xff) << 0)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x3c
-# define PORT_ID0(x) (((x) & 0xffffffff) << 0)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x3d
-# define PORT_ID1(x) (((x) & 0xffffffff) << 0)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x3e
-# define DESCRIPTION0(x) (((x) & 0xff) << 0)
-# define DESCRIPTION1(x) (((x) & 0xff) << 8)
-# define DESCRIPTION2(x) (((x) & 0xff) << 16)
-# define DESCRIPTION3(x) (((x) & 0xff) << 24)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x3f
-# define DESCRIPTION4(x) (((x) & 0xff) << 0)
-# define DESCRIPTION5(x) (((x) & 0xff) << 8)
-# define DESCRIPTION6(x) (((x) & 0xff) << 16)
-# define DESCRIPTION7(x) (((x) & 0xff) << 24)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x40
-# define DESCRIPTION8(x) (((x) & 0xff) << 0)
-# define DESCRIPTION9(x) (((x) & 0xff) << 8)
-# define DESCRIPTION10(x) (((x) & 0xff) << 16)
-# define DESCRIPTION11(x) (((x) & 0xff) << 24)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x41
-# define DESCRIPTION12(x) (((x) & 0xff) << 0)
-# define DESCRIPTION13(x) (((x) & 0xff) << 8)
-# define DESCRIPTION14(x) (((x) & 0xff) << 16)
-# define DESCRIPTION15(x) (((x) & 0xff) << 24)
-#define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x42
-# define DESCRIPTION16(x) (((x) & 0xff) << 0)
-# define DESCRIPTION17(x) (((x) & 0xff) << 8)
-
#define AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL 0x54
# define AUDIO_ENABLED (1 << 31)
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c
index d700698..9364129 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -1873,9 +1873,9 @@ int trinity_dpm_init(struct radeon_device *rdev)
pi->enable_sclk_ds = true;
pi->enable_gfx_power_gating = true;
pi->enable_gfx_clock_gating = true;
- pi->enable_mg_clock_gating = false;
- pi->enable_gfx_dynamic_mgpg = false;
- pi->override_dynamic_mgpg = false;
+ pi->enable_mg_clock_gating = true;
+ pi->enable_gfx_dynamic_mgpg = true; /* ??? */
+ pi->override_dynamic_mgpg = true;
pi->enable_auto_thermal_throttling = true;
pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */
pi->uvd_dpm = true; /* ??? */
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c
index d4a68af..7266805 100644
--- a/drivers/gpu/drm/radeon/uvd_v1_0.c
+++ b/drivers/gpu/drm/radeon/uvd_v1_0.c
@@ -357,7 +357,7 @@ int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
*
* Emit a semaphore command (either wait or signal) to the UVD ring.
*/
-bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
+void uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait)
@@ -372,8 +372,6 @@ bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
radeon_ring_write(ring, emit_wait ? 1 : 0);
-
- return true;
}
/**
diff --git a/drivers/gpu/drm/radeon/uvd_v3_1.c b/drivers/gpu/drm/radeon/uvd_v3_1.c
index d722db2..5b6fa1f 100644
--- a/drivers/gpu/drm/radeon/uvd_v3_1.c
+++ b/drivers/gpu/drm/radeon/uvd_v3_1.c
@@ -37,7 +37,7 @@
*
* Emit a semaphore command (either wait or signal) to the UVD ring.
*/
-bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
+void uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
struct radeon_ring *ring,
struct radeon_semaphore *semaphore,
bool emit_wait)
@@ -52,6 +52,4 @@ bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
-
- return true;
}
diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
index d8e835a..c590cd9 100644
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ b/drivers/gpu/drm/rcar-du/Kconfig
@@ -4,7 +4,6 @@ config DRM_RCAR_DU
select DRM_KMS_HELPER
select DRM_KMS_CMA_HELPER
select DRM_GEM_CMA_HELPER
- select DRM_KMS_FB_HELPER
help
Choose this option if you have an R-Car chipset.
If M is selected the module will be called rcar-du-drm.
diff --git a/drivers/gpu/drm/shmobile/Kconfig b/drivers/gpu/drm/shmobile/Kconfig
index 2ee44ca..ca498d1 100644
--- a/drivers/gpu/drm/shmobile/Kconfig
+++ b/drivers/gpu/drm/shmobile/Kconfig
@@ -1,9 +1,7 @@
config DRM_SHMOBILE
tristate "DRM Support for SH Mobile"
depends on DRM && (ARM || SUPERH)
- select BACKLIGHT_CLASS_DEVICE
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_KMS_CMA_HELPER
select DRM_GEM_CMA_HELPER
help
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index 562f9a4..54bad98 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -40,7 +40,7 @@
static void shmob_drm_clk_on(struct shmob_drm_device *sdev)
{
if (sdev->clock)
- clk_prepare_enable(sdev->clock);
+ clk_enable(sdev->clock);
#if 0
if (sdev->meram_dev && sdev->meram_dev->pdev)
pm_runtime_get_sync(&sdev->meram_dev->pdev->dev);
@@ -54,7 +54,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
pm_runtime_put_sync(&sdev->meram_dev->pdev->dev);
#endif
if (sdev->clock)
- clk_disable_unprepare(sdev->clock);
+ clk_disable(sdev->clock);
}
/* -----------------------------------------------------------------------------
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index edc76ab..0000000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := \
- bus.o \
- drm.o \
- gem.o \
- fb.o \
- dc.o \
- output.o \
- rgb.o \
- hdmi.o \
- gr2d.o \
- gr3d.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/drm/tegra/bus.c b/drivers/gpu/drm/tegra/bus.c
deleted file mode 100644
index 565f8f7..0000000
--- a/drivers/gpu/drm/tegra/bus.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "drm.h"
-
-static int drm_host1x_set_busid(struct drm_device *dev,
- struct drm_master *master)
-{
- const char *device = dev_name(dev->dev);
- const char *driver = dev->driver->name;
- const char *bus = dev->dev->bus->name;
- int length;
-
- master->unique_len = strlen(bus) + 1 + strlen(device);
- master->unique_size = master->unique_len;
-
- master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
- if (!master->unique)
- return -ENOMEM;
-
- snprintf(master->unique, master->unique_len + 1, "%s:%s", bus, device);
-
- length = strlen(driver) + 1 + master->unique_len;
-
- dev->devname = kmalloc(length + 1, GFP_KERNEL);
- if (!dev->devname)
- return -ENOMEM;
-
- snprintf(dev->devname, length + 1, "%s@%s", driver, master->unique);
-
- return 0;
-}
-
-static struct drm_bus drm_host1x_bus = {
- .bus_type = DRIVER_BUS_HOST1X,
- .set_busid = drm_host1x_set_busid,
-};
-
-int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device)
-{
- struct drm_device *drm;
- int ret;
-
- INIT_LIST_HEAD(&driver->device_list);
- driver->bus = &drm_host1x_bus;
-
- drm = drm_dev_alloc(driver, &device->dev);
- if (!drm)
- return -ENOMEM;
-
- ret = drm_dev_register(drm, 0);
- if (ret)
- goto err_free;
-
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name,
- driver->major, driver->minor, driver->patchlevel,
- driver->date, drm->primary->index);
-
- return 0;
-
-err_free:
- drm_dev_free(drm);
- return ret;
-}
-
-void drm_host1x_exit(struct drm_driver *driver, struct host1x_device *device)
-{
- struct tegra_drm *tegra = dev_get_drvdata(&device->dev);
-
- drm_put_dev(tegra->drm);
-}
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
deleted file mode 100644
index 07eba59..0000000
--- a/drivers/gpu/drm/tegra/drm.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/host1x.h>
-
-#include "drm.h"
-#include "gem.h"
-
-#define DRIVER_NAME "tegra"
-#define DRIVER_DESC "NVIDIA Tegra graphics"
-#define DRIVER_DATE "20120330"
-#define DRIVER_MAJOR 0
-#define DRIVER_MINOR 0
-#define DRIVER_PATCHLEVEL 0
-
-struct tegra_drm_file {
- struct list_head contexts;
-};
-
-static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
-{
- struct host1x_device *device = to_host1x_device(drm->dev);
- struct tegra_drm *tegra;
- int err;
-
- tegra = kzalloc(sizeof(*tegra), GFP_KERNEL);
- if (!tegra)
- return -ENOMEM;
-
- dev_set_drvdata(drm->dev, tegra);
- mutex_init(&tegra->clients_lock);
- INIT_LIST_HEAD(&tegra->clients);
- drm->dev_private = tegra;
- tegra->drm = drm;
-
- drm_mode_config_init(drm);
-
- err = host1x_device_init(device);
- if (err < 0)
- return err;
-
- /*
- * We don't use the drm_irq_install() helpers provided by the DRM
- * core, so we need to set this manually in order to allow the
- * DRM_IOCTL_WAIT_VBLANK to operate correctly.
- */
- drm->irq_enabled = true;
-
- err = drm_vblank_init(drm, drm->mode_config.num_crtc);
- if (err < 0)
- return err;
-
- err = tegra_drm_fb_init(drm);
- if (err < 0)
- return err;
-
- drm_kms_helper_poll_init(drm);
-
- return 0;
-}
-
-static int tegra_drm_unload(struct drm_device *drm)
-{
- struct host1x_device *device = to_host1x_device(drm->dev);
- int err;
-
- drm_kms_helper_poll_fini(drm);
- tegra_drm_fb_exit(drm);
- drm_vblank_cleanup(drm);
- drm_mode_config_cleanup(drm);
-
- err = host1x_device_exit(device);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
-{
- struct tegra_drm_file *fpriv;
-
- fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
- if (!fpriv)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&fpriv->contexts);
- filp->driver_priv = fpriv;
-
- return 0;
-}
-
-static void tegra_drm_context_free(struct tegra_drm_context *context)
-{
- context->client->ops->close_channel(context);
- kfree(context);
-}
-
-static void tegra_drm_lastclose(struct drm_device *drm)
-{
- struct tegra_drm *tegra = drm->dev_private;
-
- tegra_fbdev_restore_mode(tegra->fbdev);
-}
-
-static struct host1x_bo *
-host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle)
-{
- struct drm_gem_object *gem;
- struct tegra_bo *bo;
-
- gem = drm_gem_object_lookup(drm, file, handle);
- if (!gem)
- return NULL;
-
- mutex_lock(&drm->struct_mutex);
- drm_gem_object_unreference(gem);
- mutex_unlock(&drm->struct_mutex);
-
- bo = to_tegra_bo(gem);
- return &bo->base;
-}
-
-int tegra_drm_submit(struct tegra_drm_context *context,
- struct drm_tegra_submit *args, struct drm_device *drm,
- struct drm_file *file)
-{
- unsigned int num_cmdbufs = args->num_cmdbufs;
- unsigned int num_relocs = args->num_relocs;
- unsigned int num_waitchks = args->num_waitchks;
- struct drm_tegra_cmdbuf __user *cmdbufs =
- (void __user *)(uintptr_t)args->cmdbufs;
- struct drm_tegra_reloc __user *relocs =
- (void __user *)(uintptr_t)args->relocs;
- struct drm_tegra_waitchk __user *waitchks =
- (void __user *)(uintptr_t)args->waitchks;
- struct drm_tegra_syncpt syncpt;
- struct host1x_job *job;
- int err;
-
- /* We don't yet support other than one syncpt_incr struct per submit */
- if (args->num_syncpts != 1)
- return -EINVAL;
-
- job = host1x_job_alloc(context->channel, args->num_cmdbufs,
- args->num_relocs, args->num_waitchks);
- if (!job)
- return -ENOMEM;
-
- job->num_relocs = args->num_relocs;
- job->num_waitchk = args->num_waitchks;
- job->client = (u32)args->context;
- job->class = context->client->base.class;
- job->serialize = true;
-
- while (num_cmdbufs) {
- struct drm_tegra_cmdbuf cmdbuf;
- struct host1x_bo *bo;
-
- if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) {
- err = -EFAULT;
- goto fail;
- }
-
- bo = host1x_bo_lookup(drm, file, cmdbuf.handle);
- if (!bo) {
- err = -ENOENT;
- goto fail;
- }
-
- host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset);
- num_cmdbufs--;
- cmdbufs++;
- }
-
- if (copy_from_user(job->relocarray, relocs,
- sizeof(*relocs) * num_relocs)) {
- err = -EFAULT;
- goto fail;
- }
-
- while (num_relocs--) {
- struct host1x_reloc *reloc = &job->relocarray[num_relocs];
- struct host1x_bo *cmdbuf, *target;
-
- cmdbuf = host1x_bo_lookup(drm, file, (u32)reloc->cmdbuf);
- target = host1x_bo_lookup(drm, file, (u32)reloc->target);
-
- reloc->cmdbuf = cmdbuf;
- reloc->target = target;
-
- if (!reloc->target || !reloc->cmdbuf) {
- err = -ENOENT;
- goto fail;
- }
- }
-
- if (copy_from_user(job->waitchk, waitchks,
- sizeof(*waitchks) * num_waitchks)) {
- err = -EFAULT;
- goto fail;
- }
-
- if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts,
- sizeof(syncpt))) {
- err = -EFAULT;
- goto fail;
- }
-
- job->is_addr_reg = context->client->ops->is_addr_reg;
- job->syncpt_incrs = syncpt.incrs;
- job->syncpt_id = syncpt.id;
- job->timeout = 10000;
-
- if (args->timeout && args->timeout < 10000)
- job->timeout = args->timeout;
-
- err = host1x_job_pin(job, context->client->base.dev);
- if (err)
- goto fail;
-
- err = host1x_job_submit(job);
- if (err)
- goto fail_submit;
-
- args->fence = job->syncpt_end;
-
- host1x_job_put(job);
- return 0;
-
-fail_submit:
- host1x_job_unpin(job);
-fail:
- host1x_job_put(job);
- return err;
-}
-
-
-#ifdef CONFIG_DRM_TEGRA_STAGING
-static struct tegra_drm_context *tegra_drm_get_context(__u64 context)
-{
- return (struct tegra_drm_context *)(uintptr_t)context;
-}
-
-static bool tegra_drm_file_owns_context(struct tegra_drm_file *file,
- struct tegra_drm_context *context)
-{
- struct tegra_drm_context *ctx;
-
- list_for_each_entry(ctx, &file->contexts, list)
- if (ctx == context)
- return true;
-
- return false;
-}
-
-static int tegra_gem_create(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct drm_tegra_gem_create *args = data;
- struct tegra_bo *bo;
-
- bo = tegra_bo_create_with_handle(file, drm, args->size, args->flags,
- &args->handle);
- if (IS_ERR(bo))
- return PTR_ERR(bo);
-
- return 0;
-}
-
-static int tegra_gem_mmap(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct drm_tegra_gem_mmap *args = data;
- struct drm_gem_object *gem;
- struct tegra_bo *bo;
-
- gem = drm_gem_object_lookup(drm, file, args->handle);
- if (!gem)
- return -EINVAL;
-
- bo = to_tegra_bo(gem);
-
- args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
-
- drm_gem_object_unreference(gem);
-
- return 0;
-}
-
-static int tegra_syncpt_read(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct host1x *host = dev_get_drvdata(drm->dev->parent);
- struct drm_tegra_syncpt_read *args = data;
- struct host1x_syncpt *sp;
-
- sp = host1x_syncpt_get(host, args->id);
- if (!sp)
- return -EINVAL;
-
- args->value = host1x_syncpt_read_min(sp);
- return 0;
-}
-
-static int tegra_syncpt_incr(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
- struct drm_tegra_syncpt_incr *args = data;
- struct host1x_syncpt *sp;
-
- sp = host1x_syncpt_get(host1x, args->id);
- if (!sp)
- return -EINVAL;
-
- return host1x_syncpt_incr(sp);
-}
-
-static int tegra_syncpt_wait(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
- struct drm_tegra_syncpt_wait *args = data;
- struct host1x_syncpt *sp;
-
- sp = host1x_syncpt_get(host1x, args->id);
- if (!sp)
- return -EINVAL;
-
- return host1x_syncpt_wait(sp, args->thresh, args->timeout,
- &args->value);
-}
-
-static int tegra_open_channel(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct tegra_drm_file *fpriv = file->driver_priv;
- struct tegra_drm *tegra = drm->dev_private;
- struct drm_tegra_open_channel *args = data;
- struct tegra_drm_context *context;
- struct tegra_drm_client *client;
- int err = -ENODEV;
-
- context = kzalloc(sizeof(*context), GFP_KERNEL);
- if (!context)
- return -ENOMEM;
-
- list_for_each_entry(client, &tegra->clients, list)
- if (client->base.class == args->client) {
- err = client->ops->open_channel(client, context);
- if (err)
- break;
-
- list_add(&context->list, &fpriv->contexts);
- args->context = (uintptr_t)context;
- context->client = client;
- return 0;
- }
-
- kfree(context);
- return err;
-}
-
-static int tegra_close_channel(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct tegra_drm_file *fpriv = file->driver_priv;
- struct drm_tegra_close_channel *args = data;
- struct tegra_drm_context *context;
-
- context = tegra_drm_get_context(args->context);
-
- if (!tegra_drm_file_owns_context(fpriv, context))
- return -EINVAL;
-
- list_del(&context->list);
- tegra_drm_context_free(context);
-
- return 0;
-}
-
-static int tegra_get_syncpt(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct tegra_drm_file *fpriv = file->driver_priv;
- struct drm_tegra_get_syncpt *args = data;
- struct tegra_drm_context *context;
- struct host1x_syncpt *syncpt;
-
- context = tegra_drm_get_context(args->context);
-
- if (!tegra_drm_file_owns_context(fpriv, context))
- return -ENODEV;
-
- if (args->index >= context->client->base.num_syncpts)
- return -EINVAL;
-
- syncpt = context->client->base.syncpts[args->index];
- args->id = host1x_syncpt_id(syncpt);
-
- return 0;
-}
-
-static int tegra_submit(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct tegra_drm_file *fpriv = file->driver_priv;
- struct drm_tegra_submit *args = data;
- struct tegra_drm_context *context;
-
- context = tegra_drm_get_context(args->context);
-
- if (!tegra_drm_file_owns_context(fpriv, context))
- return -ENODEV;
-
- return context->client->ops->submit(context, args, drm, file);
-}
-
-static int tegra_get_syncpt_base(struct drm_device *drm, void *data,
- struct drm_file *file)
-{
- struct tegra_drm_file *fpriv = file->driver_priv;
- struct drm_tegra_get_syncpt_base *args = data;
- struct tegra_drm_context *context;
- struct host1x_syncpt_base *base;
- struct host1x_syncpt *syncpt;
-
- context = tegra_drm_get_context(args->context);
-
- if (!tegra_drm_file_owns_context(fpriv, context))
- return -ENODEV;
-
- if (args->syncpt >= context->client->base.num_syncpts)
- return -EINVAL;
-
- syncpt = context->client->base.syncpts[args->syncpt];
-
- base = host1x_syncpt_get_base(syncpt);
- if (!base)
- return -ENXIO;
-
- args->id = host1x_syncpt_base_id(base);
-
- return 0;
-}
-#endif
-
-static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
-#ifdef CONFIG_DRM_TEGRA_STAGING
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_UNLOCKED | DRM_AUTH),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, DRM_UNLOCKED),
-#endif
-};
-
-static const struct file_operations tegra_drm_fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .mmap = tegra_drm_mmap,
- .poll = drm_poll,
- .read = drm_read,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = drm_compat_ioctl,
-#endif
- .llseek = noop_llseek,
-};
-
-static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe)
-{
- struct drm_crtc *crtc;
-
- list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) {
- struct tegra_dc *dc = to_tegra_dc(crtc);
-
- if (dc->pipe == pipe)
- return crtc;
- }
-
- return NULL;
-}
-
-static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc)
-{
- /* TODO: implement real hardware counter using syncpoints */
- return drm_vblank_count(dev, crtc);
-}
-
-static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)
-{
- struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
- struct tegra_dc *dc = to_tegra_dc(crtc);
-
- if (!crtc)
- return -ENODEV;
-
- tegra_dc_enable_vblank(dc);
-
- return 0;
-}
-
-static void tegra_drm_disable_vblank(struct drm_device *drm, int pipe)
-{
- struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
- struct tegra_dc *dc = to_tegra_dc(crtc);
-
- if (crtc)
- tegra_dc_disable_vblank(dc);
-}
-
-static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file)
-{
- struct tegra_drm_file *fpriv = file->driver_priv;
- struct tegra_drm_context *context, *tmp;
- struct drm_crtc *crtc;
-
- list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
- tegra_dc_cancel_page_flip(crtc, file);
-
- list_for_each_entry_safe(context, tmp, &fpriv->contexts, list)
- tegra_drm_context_free(context);
-
- kfree(fpriv);
-}
-
-#ifdef CONFIG_DEBUG_FS
-static int tegra_debugfs_framebuffers(struct seq_file *s, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *)s->private;
- struct drm_device *drm = node->minor->dev;
- struct drm_framebuffer *fb;
-
- mutex_lock(&drm->mode_config.fb_lock);
-
- list_for_each_entry(fb, &drm->mode_config.fb_list, head) {
- seq_printf(s, "%3d: user size: %d x %d, depth %d, %d bpp, refcount %d\n",
- fb->base.id, fb->width, fb->height, fb->depth,
- fb->bits_per_pixel,
- atomic_read(&fb->refcount.refcount));
- }
-
- mutex_unlock(&drm->mode_config.fb_lock);
-
- return 0;
-}
-
-static struct drm_info_list tegra_debugfs_list[] = {
- { "framebuffers", tegra_debugfs_framebuffers, 0 },
-};
-
-static int tegra_debugfs_init(struct drm_minor *minor)
-{
- return drm_debugfs_create_files(tegra_debugfs_list,
- ARRAY_SIZE(tegra_debugfs_list),
- minor->debugfs_root, minor);
-}
-
-static void tegra_debugfs_cleanup(struct drm_minor *minor)
-{
- drm_debugfs_remove_files(tegra_debugfs_list,
- ARRAY_SIZE(tegra_debugfs_list), minor);
-}
-#endif
-
-static struct drm_driver tegra_drm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM,
- .load = tegra_drm_load,
- .unload = tegra_drm_unload,
- .open = tegra_drm_open,
- .preclose = tegra_drm_preclose,
- .lastclose = tegra_drm_lastclose,
-
- .get_vblank_counter = tegra_drm_get_vblank_counter,
- .enable_vblank = tegra_drm_enable_vblank,
- .disable_vblank = tegra_drm_disable_vblank,
-
-#if defined(CONFIG_DEBUG_FS)
- .debugfs_init = tegra_debugfs_init,
- .debugfs_cleanup = tegra_debugfs_cleanup,
-#endif
-
- .gem_free_object = tegra_bo_free_object,
- .gem_vm_ops = &tegra_bo_vm_ops,
- .dumb_create = tegra_bo_dumb_create,
- .dumb_map_offset = tegra_bo_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
-
- .ioctls = tegra_drm_ioctls,
- .num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
- .fops = &tegra_drm_fops,
-
- .name = DRIVER_NAME,
- .desc = DRIVER_DESC,
- .date = DRIVER_DATE,
- .major = DRIVER_MAJOR,
- .minor = DRIVER_MINOR,
- .patchlevel = DRIVER_PATCHLEVEL,
-};
-
-int tegra_drm_register_client(struct tegra_drm *tegra,
- struct tegra_drm_client *client)
-{
- mutex_lock(&tegra->clients_lock);
- list_add_tail(&client->list, &tegra->clients);
- mutex_unlock(&tegra->clients_lock);
-
- return 0;
-}
-
-int tegra_drm_unregister_client(struct tegra_drm *tegra,
- struct tegra_drm_client *client)
-{
- mutex_lock(&tegra->clients_lock);
- list_del_init(&client->list);
- mutex_unlock(&tegra->clients_lock);
-
- return 0;
-}
-
-static int host1x_drm_probe(struct host1x_device *device)
-{
- return drm_host1x_init(&tegra_drm_driver, device);
-}
-
-static int host1x_drm_remove(struct host1x_device *device)
-{
- drm_host1x_exit(&tegra_drm_driver, device);
-
- return 0;
-}
-
-static const struct of_device_id host1x_drm_subdevs[] = {
- { .compatible = "nvidia,tegra20-dc", },
- { .compatible = "nvidia,tegra20-hdmi", },
- { .compatible = "nvidia,tegra20-gr2d", },
- { .compatible = "nvidia,tegra20-gr3d", },
- { .compatible = "nvidia,tegra30-dc", },
- { .compatible = "nvidia,tegra30-hdmi", },
- { .compatible = "nvidia,tegra30-gr2d", },
- { .compatible = "nvidia,tegra30-gr3d", },
- { .compatible = "nvidia,tegra114-hdmi", },
- { .compatible = "nvidia,tegra114-gr3d", },
- { /* sentinel */ }
-};
-
-static struct host1x_driver host1x_drm_driver = {
- .name = "drm",
- .probe = host1x_drm_probe,
- .remove = host1x_drm_remove,
- .subdevs = host1x_drm_subdevs,
-};
-
-static int __init host1x_drm_init(void)
-{
- int err;
-
- err = host1x_driver_register(&host1x_drm_driver);
- if (err < 0)
- return err;
-
- err = platform_driver_register(&tegra_dc_driver);
- if (err < 0)
- goto unregister_host1x;
-
- err = platform_driver_register(&tegra_hdmi_driver);
- if (err < 0)
- goto unregister_dc;
-
- err = platform_driver_register(&tegra_gr2d_driver);
- if (err < 0)
- goto unregister_hdmi;
-
- err = platform_driver_register(&tegra_gr3d_driver);
- if (err < 0)
- goto unregister_gr2d;
-
- return 0;
-
-unregister_gr2d:
- platform_driver_unregister(&tegra_gr2d_driver);
-unregister_hdmi:
- platform_driver_unregister(&tegra_hdmi_driver);
-unregister_dc:
- platform_driver_unregister(&tegra_dc_driver);
-unregister_host1x:
- host1x_driver_unregister(&host1x_drm_driver);
- return err;
-}
-module_init(host1x_drm_init);
-
-static void __exit host1x_drm_exit(void)
-{
- platform_driver_unregister(&tegra_gr3d_driver);
- platform_driver_unregister(&tegra_gr2d_driver);
- platform_driver_unregister(&tegra_hdmi_driver);
- platform_driver_unregister(&tegra_dc_driver);
- host1x_driver_unregister(&host1x_drm_driver);
-}
-module_exit(host1x_drm_exit);
-
-MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
-MODULE_DESCRIPTION("NVIDIA Tegra DRM driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
deleted file mode 100644
index 7ec4259..0000000
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (c) 2012-2013, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/clk.h>
-
-#include "drm.h"
-#include "gem.h"
-#include "gr2d.h"
-
-struct gr2d {
- struct tegra_drm_client client;
- struct host1x_channel *channel;
- struct clk *clk;
-
- DECLARE_BITMAP(addr_regs, GR2D_NUM_REGS);
-};
-
-static inline struct gr2d *to_gr2d(struct tegra_drm_client *client)
-{
- return container_of(client, struct gr2d, client);
-}
-
-static int gr2d_init(struct host1x_client *client)
-{
- struct tegra_drm_client *drm = host1x_to_drm_client(client);
- struct tegra_drm *tegra = dev_get_drvdata(client->parent);
- unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
- struct gr2d *gr2d = to_gr2d(drm);
-
- gr2d->channel = host1x_channel_request(client->dev);
- if (!gr2d->channel)
- return -ENOMEM;
-
- client->syncpts[0] = host1x_syncpt_request(client->dev, flags);
- if (!client->syncpts[0]) {
- host1x_channel_free(gr2d->channel);
- return -ENOMEM;
- }
-
- return tegra_drm_register_client(tegra, drm);
-}
-
-static int gr2d_exit(struct host1x_client *client)
-{
- struct tegra_drm_client *drm = host1x_to_drm_client(client);
- struct tegra_drm *tegra = dev_get_drvdata(client->parent);
- struct gr2d *gr2d = to_gr2d(drm);
- int err;
-
- err = tegra_drm_unregister_client(tegra, drm);
- if (err < 0)
- return err;
-
- host1x_syncpt_free(client->syncpts[0]);
- host1x_channel_free(gr2d->channel);
-
- return 0;
-}
-
-static const struct host1x_client_ops gr2d_client_ops = {
- .init = gr2d_init,
- .exit = gr2d_exit,
-};
-
-static int gr2d_open_channel(struct tegra_drm_client *client,
- struct tegra_drm_context *context)
-{
- struct gr2d *gr2d = to_gr2d(client);
-
- context->channel = host1x_channel_get(gr2d->channel);
- if (!context->channel)
- return -ENOMEM;
-
- return 0;
-}
-
-static void gr2d_close_channel(struct tegra_drm_context *context)
-{
- host1x_channel_put(context->channel);
-}
-
-static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset)
-{
- struct gr2d *gr2d = dev_get_drvdata(dev);
-
- switch (class) {
- case HOST1X_CLASS_HOST1X:
- if (offset == 0x2b)
- return 1;
-
- break;
-
- case HOST1X_CLASS_GR2D:
- case HOST1X_CLASS_GR2D_SB:
- if (offset >= GR2D_NUM_REGS)
- break;
-
- if (test_bit(offset, gr2d->addr_regs))
- return 1;
-
- break;
- }
-
- return 0;
-}
-
-static const struct tegra_drm_client_ops gr2d_ops = {
- .open_channel = gr2d_open_channel,
- .close_channel = gr2d_close_channel,
- .is_addr_reg = gr2d_is_addr_reg,
- .submit = tegra_drm_submit,
-};
-
-static const struct of_device_id gr2d_match[] = {
- { .compatible = "nvidia,tegra30-gr2d" },
- { .compatible = "nvidia,tegra20-gr2d" },
- { },
-};
-
-static const u32 gr2d_addr_regs[] = {
- GR2D_UA_BASE_ADDR,
- GR2D_VA_BASE_ADDR,
- GR2D_PAT_BASE_ADDR,
- GR2D_DSTA_BASE_ADDR,
- GR2D_DSTB_BASE_ADDR,
- GR2D_DSTC_BASE_ADDR,
- GR2D_SRCA_BASE_ADDR,
- GR2D_SRCB_BASE_ADDR,
- GR2D_SRC_BASE_ADDR_SB,
- GR2D_DSTA_BASE_ADDR_SB,
- GR2D_DSTB_BASE_ADDR_SB,
- GR2D_UA_BASE_ADDR_SB,
- GR2D_VA_BASE_ADDR_SB,
-};
-
-static int gr2d_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct host1x_syncpt **syncpts;
- struct gr2d *gr2d;
- unsigned int i;
- int err;
-
- gr2d = devm_kzalloc(dev, sizeof(*gr2d), GFP_KERNEL);
- if (!gr2d)
- return -ENOMEM;
-
- syncpts = devm_kzalloc(dev, sizeof(*syncpts), GFP_KERNEL);
- if (!syncpts)
- return -ENOMEM;
-
- gr2d->clk = devm_clk_get(dev, NULL);
- if (IS_ERR(gr2d->clk)) {
- dev_err(dev, "cannot get clock\n");
- return PTR_ERR(gr2d->clk);
- }
-
- err = clk_prepare_enable(gr2d->clk);
- if (err) {
- dev_err(dev, "cannot turn on clock\n");
- return err;
- }
-
- INIT_LIST_HEAD(&gr2d->client.base.list);
- gr2d->client.base.ops = &gr2d_client_ops;
- gr2d->client.base.dev = dev;
- gr2d->client.base.class = HOST1X_CLASS_GR2D;
- gr2d->client.base.syncpts = syncpts;
- gr2d->client.base.num_syncpts = 1;
-
- INIT_LIST_HEAD(&gr2d->client.list);
- gr2d->client.ops = &gr2d_ops;
-
- err = host1x_client_register(&gr2d->client.base);
- if (err < 0) {
- dev_err(dev, "failed to register host1x client: %d\n", err);
- clk_disable_unprepare(gr2d->clk);
- return err;
- }
-
- /* initialize address register map */
- for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); i++)
- set_bit(gr2d_addr_regs[i], gr2d->addr_regs);
-
- platform_set_drvdata(pdev, gr2d);
-
- return 0;
-}
-
-static int gr2d_remove(struct platform_device *pdev)
-{
- struct gr2d *gr2d = platform_get_drvdata(pdev);
- int err;
-
- err = host1x_client_unregister(&gr2d->client.base);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
- err);
- return err;
- }
-
- clk_disable_unprepare(gr2d->clk);
-
- return 0;
-}
-
-struct platform_driver tegra_gr2d_driver = {
- .driver = {
- .name = "tegra-gr2d",
- .of_match_table = gr2d_match,
- },
- .probe = gr2d_probe,
- .remove = gr2d_remove,
-};
diff --git a/drivers/gpu/drm/tegra/gr2d.h b/drivers/gpu/drm/tegra/gr2d.h
deleted file mode 100644
index 4d7304f..0000000
--- a/drivers/gpu/drm/tegra/gr2d.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef TEGRA_GR2D_H
-#define TEGRA_GR2D_H
-
-#define GR2D_UA_BASE_ADDR 0x1a
-#define GR2D_VA_BASE_ADDR 0x1b
-#define GR2D_PAT_BASE_ADDR 0x26
-#define GR2D_DSTA_BASE_ADDR 0x2b
-#define GR2D_DSTB_BASE_ADDR 0x2c
-#define GR2D_DSTC_BASE_ADDR 0x2d
-#define GR2D_SRCA_BASE_ADDR 0x31
-#define GR2D_SRCB_BASE_ADDR 0x32
-#define GR2D_SRC_BASE_ADDR_SB 0x48
-#define GR2D_DSTA_BASE_ADDR_SB 0x49
-#define GR2D_DSTB_BASE_ADDR_SB 0x4a
-#define GR2D_UA_BASE_ADDR_SB 0x4b
-#define GR2D_VA_BASE_ADDR_SB 0x4c
-
-#define GR2D_NUM_REGS 0x4d
-
-#endif
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
deleted file mode 100644
index 4cec8f5..0000000
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2013 Avionic Design GmbH
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/host1x.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/tegra-powergate.h>
-
-#include "drm.h"
-#include "gem.h"
-#include "gr3d.h"
-
-struct gr3d {
- struct tegra_drm_client client;
- struct host1x_channel *channel;
- struct clk *clk_secondary;
- struct clk *clk;
-
- DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS);
-};
-
-static inline struct gr3d *to_gr3d(struct tegra_drm_client *client)
-{
- return container_of(client, struct gr3d, client);
-}
-
-static int gr3d_init(struct host1x_client *client)
-{
- struct tegra_drm_client *drm = host1x_to_drm_client(client);
- struct tegra_drm *tegra = dev_get_drvdata(client->parent);
- unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
- struct gr3d *gr3d = to_gr3d(drm);
-
- gr3d->channel = host1x_channel_request(client->dev);
- if (!gr3d->channel)
- return -ENOMEM;
-
- client->syncpts[0] = host1x_syncpt_request(client->dev, flags);
- if (!client->syncpts[0]) {
- host1x_channel_free(gr3d->channel);
- return -ENOMEM;
- }
-
- return tegra_drm_register_client(tegra, drm);
-}
-
-static int gr3d_exit(struct host1x_client *client)
-{
- struct tegra_drm_client *drm = host1x_to_drm_client(client);
- struct tegra_drm *tegra = dev_get_drvdata(client->parent);
- struct gr3d *gr3d = to_gr3d(drm);
- int err;
-
- err = tegra_drm_unregister_client(tegra, drm);
- if (err < 0)
- return err;
-
- host1x_syncpt_free(client->syncpts[0]);
- host1x_channel_free(gr3d->channel);
-
- return 0;
-}
-
-static const struct host1x_client_ops gr3d_client_ops = {
- .init = gr3d_init,
- .exit = gr3d_exit,
-};
-
-static int gr3d_open_channel(struct tegra_drm_client *client,
- struct tegra_drm_context *context)
-{
- struct gr3d *gr3d = to_gr3d(client);
-
- context->channel = host1x_channel_get(gr3d->channel);
- if (!context->channel)
- return -ENOMEM;
-
- return 0;
-}
-
-static void gr3d_close_channel(struct tegra_drm_context *context)
-{
- host1x_channel_put(context->channel);
-}
-
-static int gr3d_is_addr_reg(struct device *dev, u32 class, u32 offset)
-{
- struct gr3d *gr3d = dev_get_drvdata(dev);
-
- switch (class) {
- case HOST1X_CLASS_HOST1X:
- if (offset == 0x2b)
- return 1;
-
- break;
-
- case HOST1X_CLASS_GR3D:
- if (offset >= GR3D_NUM_REGS)
- break;
-
- if (test_bit(offset, gr3d->addr_regs))
- return 1;
-
- break;
- }
-
- return 0;
-}
-
-static const struct tegra_drm_client_ops gr3d_ops = {
- .open_channel = gr3d_open_channel,
- .close_channel = gr3d_close_channel,
- .is_addr_reg = gr3d_is_addr_reg,
- .submit = tegra_drm_submit,
-};
-
-static const struct of_device_id tegra_gr3d_match[] = {
- { .compatible = "nvidia,tegra114-gr3d" },
- { .compatible = "nvidia,tegra30-gr3d" },
- { .compatible = "nvidia,tegra20-gr3d" },
- { }
-};
-
-static const u32 gr3d_addr_regs[] = {
- GR3D_IDX_ATTRIBUTE( 0),
- GR3D_IDX_ATTRIBUTE( 1),
- GR3D_IDX_ATTRIBUTE( 2),
- GR3D_IDX_ATTRIBUTE( 3),
- GR3D_IDX_ATTRIBUTE( 4),
- GR3D_IDX_ATTRIBUTE( 5),
- GR3D_IDX_ATTRIBUTE( 6),
- GR3D_IDX_ATTRIBUTE( 7),
- GR3D_IDX_ATTRIBUTE( 8),
- GR3D_IDX_ATTRIBUTE( 9),
- GR3D_IDX_ATTRIBUTE(10),
- GR3D_IDX_ATTRIBUTE(11),
- GR3D_IDX_ATTRIBUTE(12),
- GR3D_IDX_ATTRIBUTE(13),
- GR3D_IDX_ATTRIBUTE(14),
- GR3D_IDX_ATTRIBUTE(15),
- GR3D_IDX_INDEX_BASE,
- GR3D_QR_ZTAG_ADDR,
- GR3D_QR_CTAG_ADDR,
- GR3D_QR_CZ_ADDR,
- GR3D_TEX_TEX_ADDR( 0),
- GR3D_TEX_TEX_ADDR( 1),
- GR3D_TEX_TEX_ADDR( 2),
- GR3D_TEX_TEX_ADDR( 3),
- GR3D_TEX_TEX_ADDR( 4),
- GR3D_TEX_TEX_ADDR( 5),
- GR3D_TEX_TEX_ADDR( 6),
- GR3D_TEX_TEX_ADDR( 7),
- GR3D_TEX_TEX_ADDR( 8),
- GR3D_TEX_TEX_ADDR( 9),
- GR3D_TEX_TEX_ADDR(10),
- GR3D_TEX_TEX_ADDR(11),
- GR3D_TEX_TEX_ADDR(12),
- GR3D_TEX_TEX_ADDR(13),
- GR3D_TEX_TEX_ADDR(14),
- GR3D_TEX_TEX_ADDR(15),
- GR3D_DW_MEMORY_OUTPUT_ADDRESS,
- GR3D_GLOBAL_SURFADDR( 0),
- GR3D_GLOBAL_SURFADDR( 1),
- GR3D_GLOBAL_SURFADDR( 2),
- GR3D_GLOBAL_SURFADDR( 3),
- GR3D_GLOBAL_SURFADDR( 4),
- GR3D_GLOBAL_SURFADDR( 5),
- GR3D_GLOBAL_SURFADDR( 6),
- GR3D_GLOBAL_SURFADDR( 7),
- GR3D_GLOBAL_SURFADDR( 8),
- GR3D_GLOBAL_SURFADDR( 9),
- GR3D_GLOBAL_SURFADDR(10),
- GR3D_GLOBAL_SURFADDR(11),
- GR3D_GLOBAL_SURFADDR(12),
- GR3D_GLOBAL_SURFADDR(13),
- GR3D_GLOBAL_SURFADDR(14),
- GR3D_GLOBAL_SURFADDR(15),
- GR3D_GLOBAL_SPILLSURFADDR,
- GR3D_GLOBAL_SURFOVERADDR( 0),
- GR3D_GLOBAL_SURFOVERADDR( 1),
- GR3D_GLOBAL_SURFOVERADDR( 2),
- GR3D_GLOBAL_SURFOVERADDR( 3),
- GR3D_GLOBAL_SURFOVERADDR( 4),
- GR3D_GLOBAL_SURFOVERADDR( 5),
- GR3D_GLOBAL_SURFOVERADDR( 6),
- GR3D_GLOBAL_SURFOVERADDR( 7),
- GR3D_GLOBAL_SURFOVERADDR( 8),
- GR3D_GLOBAL_SURFOVERADDR( 9),
- GR3D_GLOBAL_SURFOVERADDR(10),
- GR3D_GLOBAL_SURFOVERADDR(11),
- GR3D_GLOBAL_SURFOVERADDR(12),
- GR3D_GLOBAL_SURFOVERADDR(13),
- GR3D_GLOBAL_SURFOVERADDR(14),
- GR3D_GLOBAL_SURFOVERADDR(15),
- GR3D_GLOBAL_SAMP01SURFADDR( 0),
- GR3D_GLOBAL_SAMP01SURFADDR( 1),
- GR3D_GLOBAL_SAMP01SURFADDR( 2),
- GR3D_GLOBAL_SAMP01SURFADDR( 3),
- GR3D_GLOBAL_SAMP01SURFADDR( 4),
- GR3D_GLOBAL_SAMP01SURFADDR( 5),
- GR3D_GLOBAL_SAMP01SURFADDR( 6),
- GR3D_GLOBAL_SAMP01SURFADDR( 7),
- GR3D_GLOBAL_SAMP01SURFADDR( 8),
- GR3D_GLOBAL_SAMP01SURFADDR( 9),
- GR3D_GLOBAL_SAMP01SURFADDR(10),
- GR3D_GLOBAL_SAMP01SURFADDR(11),
- GR3D_GLOBAL_SAMP01SURFADDR(12),
- GR3D_GLOBAL_SAMP01SURFADDR(13),
- GR3D_GLOBAL_SAMP01SURFADDR(14),
- GR3D_GLOBAL_SAMP01SURFADDR(15),
- GR3D_GLOBAL_SAMP23SURFADDR( 0),
- GR3D_GLOBAL_SAMP23SURFADDR( 1),
- GR3D_GLOBAL_SAMP23SURFADDR( 2),
- GR3D_GLOBAL_SAMP23SURFADDR( 3),
- GR3D_GLOBAL_SAMP23SURFADDR( 4),
- GR3D_GLOBAL_SAMP23SURFADDR( 5),
- GR3D_GLOBAL_SAMP23SURFADDR( 6),
- GR3D_GLOBAL_SAMP23SURFADDR( 7),
- GR3D_GLOBAL_SAMP23SURFADDR( 8),
- GR3D_GLOBAL_SAMP23SURFADDR( 9),
- GR3D_GLOBAL_SAMP23SURFADDR(10),
- GR3D_GLOBAL_SAMP23SURFADDR(11),
- GR3D_GLOBAL_SAMP23SURFADDR(12),
- GR3D_GLOBAL_SAMP23SURFADDR(13),
- GR3D_GLOBAL_SAMP23SURFADDR(14),
- GR3D_GLOBAL_SAMP23SURFADDR(15),
-};
-
-static int gr3d_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct host1x_syncpt **syncpts;
- struct gr3d *gr3d;
- unsigned int i;
- int err;
-
- gr3d = devm_kzalloc(&pdev->dev, sizeof(*gr3d), GFP_KERNEL);
- if (!gr3d)
- return -ENOMEM;
-
- syncpts = devm_kzalloc(&pdev->dev, sizeof(*syncpts), GFP_KERNEL);
- if (!syncpts)
- return -ENOMEM;
-
- gr3d->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(gr3d->clk)) {
- dev_err(&pdev->dev, "cannot get clock\n");
- return PTR_ERR(gr3d->clk);
- }
-
- if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) {
- gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2");
- if (IS_ERR(gr3d->clk)) {
- dev_err(&pdev->dev, "cannot get secondary clock\n");
- return PTR_ERR(gr3d->clk);
- }
- }
-
- err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to power up 3D unit\n");
- return err;
- }
-
- if (gr3d->clk_secondary) {
- err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1,
- gr3d->clk_secondary);
- if (err < 0) {
- dev_err(&pdev->dev,
- "failed to power up secondary 3D unit\n");
- return err;
- }
- }
-
- INIT_LIST_HEAD(&gr3d->client.base.list);
- gr3d->client.base.ops = &gr3d_client_ops;
- gr3d->client.base.dev = &pdev->dev;
- gr3d->client.base.class = HOST1X_CLASS_GR3D;
- gr3d->client.base.syncpts = syncpts;
- gr3d->client.base.num_syncpts = 1;
-
- INIT_LIST_HEAD(&gr3d->client.list);
- gr3d->client.ops = &gr3d_ops;
-
- err = host1x_client_register(&gr3d->client.base);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to register host1x client: %d\n",
- err);
- return err;
- }
-
- /* initialize address register map */
- for (i = 0; i < ARRAY_SIZE(gr3d_addr_regs); i++)
- set_bit(gr3d_addr_regs[i], gr3d->addr_regs);
-
- platform_set_drvdata(pdev, gr3d);
-
- return 0;
-}
-
-static int gr3d_remove(struct platform_device *pdev)
-{
- struct gr3d *gr3d = platform_get_drvdata(pdev);
- int err;
-
- err = host1x_client_unregister(&gr3d->client.base);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
- err);
- return err;
- }
-
- if (gr3d->clk_secondary) {
- tegra_powergate_power_off(TEGRA_POWERGATE_3D1);
- clk_disable_unprepare(gr3d->clk_secondary);
- }
-
- tegra_powergate_power_off(TEGRA_POWERGATE_3D);
- clk_disable_unprepare(gr3d->clk);
-
- return 0;
-}
-
-struct platform_driver tegra_gr3d_driver = {
- .driver = {
- .name = "tegra-gr3d",
- .of_match_table = tegra_gr3d_match,
- },
- .probe = gr3d_probe,
- .remove = gr3d_remove,
-};
diff --git a/drivers/gpu/drm/tegra/gr3d.h b/drivers/gpu/drm/tegra/gr3d.h
deleted file mode 100644
index 0c30a13..0000000
--- a/drivers/gpu/drm/tegra/gr3d.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef TEGRA_GR3D_H
-#define TEGRA_GR3D_H
-
-#define GR3D_IDX_ATTRIBUTE(x) (0x100 + (x) * 2)
-#define GR3D_IDX_INDEX_BASE 0x121
-#define GR3D_QR_ZTAG_ADDR 0x415
-#define GR3D_QR_CTAG_ADDR 0x417
-#define GR3D_QR_CZ_ADDR 0x419
-#define GR3D_TEX_TEX_ADDR(x) (0x710 + (x))
-#define GR3D_DW_MEMORY_OUTPUT_ADDRESS 0x904
-#define GR3D_GLOBAL_SURFADDR(x) (0xe00 + (x))
-#define GR3D_GLOBAL_SPILLSURFADDR 0xe2a
-#define GR3D_GLOBAL_SURFOVERADDR(x) (0xe30 + (x))
-#define GR3D_GLOBAL_SAMP01SURFADDR(x) (0xe50 + (x))
-#define GR3D_GLOBAL_SAMP23SURFADDR(x) (0xe60 + (x))
-
-#define GR3D_NUM_REGS 0xe88
-
-#endif
diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig
index 7c3ef79..7a4d101 100644
--- a/drivers/gpu/drm/tilcdc/Kconfig
+++ b/drivers/gpu/drm/tilcdc/Kconfig
@@ -2,7 +2,6 @@ config DRM_TILCDC
tristate "DRM Support for TI LCDC Display Controller"
depends on DRM && OF && ARM
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select DRM_KMS_CMA_HELPER
select DRM_GEM_CMA_HELPER
select VIDEOMODE_HELPERS
diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile
index b433b9f..b2b33dd 100644
--- a/drivers/gpu/drm/ttm/Makefile
+++ b/drivers/gpu/drm/ttm/Makefile
@@ -5,6 +5,10 @@ ccflags-y := -Iinclude/drm
ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \
ttm_bo_util.o ttm_bo_vm.o ttm_module.o \
ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o \
- ttm_bo_manager.o ttm_page_alloc_dma.o
+ ttm_bo_manager.o
+
+ifeq ($(CONFIG_SWIOTLB),y)
+ttm-y += ttm_page_alloc_dma.o
+endif
obj-$(CONFIG_DRM_TTM) += ttm.o
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 07e02c4..f1a857e 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -151,7 +151,7 @@ static void ttm_bo_release_list(struct kref *list_kref)
atomic_dec(&bo->glob->bo_count);
if (bo->resv == &bo->ttm_resv)
reservation_object_fini(&bo->ttm_resv);
- mutex_destroy(&bo->wu_mutex);
+
if (bo->destroy)
bo->destroy(bo);
else {
@@ -429,20 +429,8 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
sync_obj = driver->sync_obj_ref(bo->sync_obj);
spin_unlock(&bdev->fence_lock);
- if (!ret) {
-
- /*
- * Make NO_EVICT bos immediately available to
- * shrinkers, now that they are queued for
- * destruction.
- */
- if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) {
- bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT;
- ttm_bo_add_to_lru(bo);
- }
-
+ if (!ret)
ww_mutex_unlock(&bo->resv->lock);
- }
kref_get(&bo->list_kref);
list_add_tail(&bo->ddestroy, &bdev->ddestroy);
@@ -998,32 +986,24 @@ out_unlock:
return ret;
}
-static bool ttm_bo_mem_compat(struct ttm_placement *placement,
- struct ttm_mem_reg *mem,
- uint32_t *new_flags)
+static int ttm_bo_mem_compat(struct ttm_placement *placement,
+ struct ttm_mem_reg *mem)
{
int i;
if (mem->mm_node && placement->lpfn != 0 &&
(mem->start < placement->fpfn ||
mem->start + mem->num_pages > placement->lpfn))
- return false;
+ return -1;
for (i = 0; i < placement->num_placement; i++) {
- *new_flags = placement->placement[i];
- if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
- (*new_flags & mem->placement & TTM_PL_MASK_MEM))
- return true;
+ if ((placement->placement[i] & mem->placement &
+ TTM_PL_MASK_CACHING) &&
+ (placement->placement[i] & mem->placement &
+ TTM_PL_MASK_MEM))
+ return i;
}
-
- for (i = 0; i < placement->num_busy_placement; i++) {
- *new_flags = placement->busy_placement[i];
- if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
- (*new_flags & mem->placement & TTM_PL_MASK_MEM))
- return true;
- }
-
- return false;
+ return -1;
}
int ttm_bo_validate(struct ttm_buffer_object *bo,
@@ -1032,7 +1012,6 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
bool no_wait_gpu)
{
int ret;
- uint32_t new_flags;
lockdep_assert_held(&bo->resv->lock.base);
/* Check that range is valid */
@@ -1043,7 +1022,8 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
/*
* Check whether we need to move buffer.
*/
- if (!ttm_bo_mem_compat(placement, &bo->mem, &new_flags)) {
+ ret = ttm_bo_mem_compat(placement, &bo->mem);
+ if (ret < 0) {
ret = ttm_bo_move_buffer(bo, placement, interruptible,
no_wait_gpu);
if (ret)
@@ -1053,7 +1033,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
* Use the access and other non-mapping-related flag bits from
* the compatible memory placement flags to the active flags
*/
- ttm_flag_masked(&bo->mem.placement, new_flags,
+ ttm_flag_masked(&bo->mem.placement, placement->placement[ret],
~TTM_PL_MASK_MEMTYPE);
}
/*
@@ -1123,7 +1103,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
INIT_LIST_HEAD(&bo->ddestroy);
INIT_LIST_HEAD(&bo->swap);
INIT_LIST_HEAD(&bo->io_reserve_lru);
- mutex_init(&bo->wu_mutex);
bo->bdev = bdev;
bo->glob = bdev->glob;
bo->type = type;
@@ -1705,35 +1684,3 @@ void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
;
}
EXPORT_SYMBOL(ttm_bo_swapout_all);
-
-/**
- * ttm_bo_wait_unreserved - interruptible wait for a buffer object to become
- * unreserved
- *
- * @bo: Pointer to buffer
- */
-int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo)
-{
- int ret;
-
- /*
- * In the absense of a wait_unlocked API,
- * Use the bo::wu_mutex to avoid triggering livelocks due to
- * concurrent use of this function. Note that this use of
- * bo::wu_mutex can go away if we change locking order to
- * mmap_sem -> bo::reserve.
- */
- ret = mutex_lock_interruptible(&bo->wu_mutex);
- if (unlikely(ret != 0))
- return -ERESTARTSYS;
- if (!ww_mutex_is_locked(&bo->resv->lock))
- goto out_unlock;
- ret = ttm_bo_reserve_nolru(bo, true, false, false, NULL);
- if (unlikely(ret != 0))
- goto out_unlock;
- ww_mutex_unlock(&bo->resv->lock);
-
-out_unlock:
- mutex_unlock(&bo->wu_mutex);
- return ret;
-}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 15b86a9..7cc904d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -343,28 +343,19 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
if (ret)
goto out;
- /*
- * Single TTM move. NOP.
- */
if (old_iomap == NULL && new_iomap == NULL)
goto out2;
-
- /*
- * Don't move nonexistent data. Clear destination instead.
- */
- if (old_iomap == NULL &&
- (ttm == NULL || ttm->state == tt_unpopulated)) {
- memset_io(new_iomap, 0, new_mem->num_pages*PAGE_SIZE);
+ if (old_iomap == NULL && ttm == NULL)
goto out2;
- }
- /*
- * TTM might be null for moves within the same region.
- */
- if (ttm && ttm->state == tt_unpopulated) {
+ if (ttm->state == tt_unpopulated) {
ret = ttm->bdev->driver->ttm_tt_populate(ttm);
- if (ret)
+ if (ret) {
+ /* if we fail here don't nuke the mm node
+ * as the bo still owns it */
+ old_copy.mm_node = NULL;
goto out1;
+ }
}
add = 0;
@@ -390,8 +381,11 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
prot);
} else
ret = ttm_copy_io_page(new_iomap, old_iomap, page);
- if (ret)
+ if (ret) {
+ /* failing here, means keep old copy as-is */
+ old_copy.mm_node = NULL;
goto out1;
+ }
}
mb();
out2:
@@ -409,12 +403,7 @@ out1:
ttm_mem_reg_iounmap(bdev, old_mem, new_iomap);
out:
ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);
-
- /*
- * On error, keep the mm node!
- */
- if (!ret)
- ttm_bo_mem_put(bo, &old_copy);
+ ttm_bo_mem_put(bo, &old_copy);
return ret;
}
EXPORT_SYMBOL(ttm_bo_move_memcpy);
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index b249ab9..1006c15 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -41,51 +41,6 @@
#define TTM_BO_VM_NUM_PREFAULT 16
-static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
- struct vm_area_struct *vma,
- struct vm_fault *vmf)
-{
- struct ttm_bo_device *bdev = bo->bdev;
- int ret = 0;
-
- spin_lock(&bdev->fence_lock);
- if (likely(!test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)))
- goto out_unlock;
-
- /*
- * Quick non-stalling check for idle.
- */
- ret = ttm_bo_wait(bo, false, false, true);
- if (likely(ret == 0))
- goto out_unlock;
-
- /*
- * If possible, avoid waiting for GPU with mmap_sem
- * held.
- */
- if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
- ret = VM_FAULT_RETRY;
- if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
- goto out_unlock;
-
- up_read(&vma->vm_mm->mmap_sem);
- (void) ttm_bo_wait(bo, false, true, false);
- goto out_unlock;
- }
-
- /*
- * Ordinary wait.
- */
- ret = ttm_bo_wait(bo, false, true, false);
- if (unlikely(ret != 0))
- ret = (ret != -ERESTARTSYS) ? VM_FAULT_SIGBUS :
- VM_FAULT_NOPAGE;
-
-out_unlock:
- spin_unlock(&bdev->fence_lock);
- return ret;
-}
-
static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
@@ -102,33 +57,17 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
int retval = VM_FAULT_NOPAGE;
struct ttm_mem_type_manager *man =
&bdev->man[bo->mem.mem_type];
- struct vm_area_struct cvma;
/*
* Work around locking order reversal in fault / nopfn
* between mmap_sem and bo_reserve: Perform a trylock operation
- * for reserve, and if it fails, retry the fault after waiting
- * for the buffer to become unreserved.
+ * for reserve, and if it fails, retry the fault after scheduling.
*/
- ret = ttm_bo_reserve(bo, true, true, false, NULL);
- if (unlikely(ret != 0)) {
- if (ret != -EBUSY)
- return VM_FAULT_NOPAGE;
- if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
- if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
- up_read(&vma->vm_mm->mmap_sem);
- (void) ttm_bo_wait_unreserved(bo);
- }
-
- return VM_FAULT_RETRY;
- }
-
- /*
- * If we'd want to change locking order to
- * mmap_sem -> bo::reserve, we'd use a blocking reserve here
- * instead of retrying the fault...
- */
+ ret = ttm_bo_reserve(bo, true, true, false, 0);
+ if (unlikely(ret != 0)) {
+ if (ret == -EBUSY)
+ set_need_resched();
return VM_FAULT_NOPAGE;
}
@@ -138,6 +77,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case 0:
break;
case -EBUSY:
+ set_need_resched();
case -ERESTARTSYS:
retval = VM_FAULT_NOPAGE;
goto out_unlock;
@@ -151,11 +91,18 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
* Wait for buffer data in transit, due to a pipelined
* move.
*/
- ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
- if (unlikely(ret != 0)) {
- retval = ret;
- goto out_unlock;
- }
+
+ spin_lock(&bdev->fence_lock);
+ if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) {
+ ret = ttm_bo_wait(bo, false, true, false);
+ spin_unlock(&bdev->fence_lock);
+ if (unlikely(ret != 0)) {
+ retval = (ret != -ERESTARTSYS) ?
+ VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
+ goto out_unlock;
+ }
+ } else
+ spin_unlock(&bdev->fence_lock);
ret = ttm_mem_io_lock(man, true);
if (unlikely(ret != 0)) {
@@ -179,21 +126,26 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
/*
- * Make a local vma copy to modify the page_prot member
- * and vm_flags if necessary. The vma parameter is protected
- * by mmap_sem in write mode.
+ * Strictly, we're not allowed to modify vma->vm_page_prot here,
+ * since the mmap_sem is only held in read mode. However, we
+ * modify only the caching bits of vma->vm_page_prot and
+ * consider those bits protected by
+ * the bo->mutex, as we should be the only writers.
+ * There shouldn't really be any readers of these bits except
+ * within vm_insert_mixed()? fork?
+ *
+ * TODO: Add a list of vmas to the bo, and change the
+ * vma->vm_page_prot when the object changes caching policy, with
+ * the correct locks held.
*/
- cvma = *vma;
- cvma.vm_page_prot = vm_get_page_prot(cvma.vm_flags);
-
if (bo->mem.bus.is_iomem) {
- cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
- cvma.vm_page_prot);
+ vma->vm_page_prot = ttm_io_prot(bo->mem.placement,
+ vma->vm_page_prot);
} else {
ttm = bo->ttm;
- if (!(bo->mem.placement & TTM_PL_FLAG_CACHED))
- cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
- cvma.vm_page_prot);
+ vma->vm_page_prot = (bo->mem.placement & TTM_PL_FLAG_CACHED) ?
+ vm_get_page_prot(vma->vm_flags) :
+ ttm_io_prot(bo->mem.placement, vma->vm_page_prot);
/* Allocate all page at once, most common usage */
if (ttm->bdev->driver->ttm_tt_populate(ttm)) {
@@ -220,7 +172,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
pfn = page_to_pfn(page);
}
- ret = vm_insert_mixed(&cvma, address, pfn);
+ ret = vm_insert_mixed(vma, address, pfn);
/*
* Somebody beat us to this PTE or prefaulting to
* an already populated PTE, or prefaulting error.
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index 479e941..6c91178 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -32,7 +32,8 @@
#include <linux/sched.h>
#include <linux/module.h>
-static void ttm_eu_backoff_reservation_locked(struct list_head *list)
+static void ttm_eu_backoff_reservation_locked(struct list_head *list,
+ struct ww_acquire_ctx *ticket)
{
struct ttm_validate_buffer *entry;
@@ -92,9 +93,8 @@ void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
entry = list_first_entry(list, struct ttm_validate_buffer, head);
glob = entry->bo->glob;
spin_lock(&glob->lru_lock);
- ttm_eu_backoff_reservation_locked(list);
- if (ticket)
- ww_acquire_fini(ticket);
+ ttm_eu_backoff_reservation_locked(list, ticket);
+ ww_acquire_fini(ticket);
spin_unlock(&glob->lru_lock);
}
EXPORT_SYMBOL(ttm_eu_backoff_reservation);
@@ -130,8 +130,7 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
entry = list_first_entry(list, struct ttm_validate_buffer, head);
glob = entry->bo->glob;
- if (ticket)
- ww_acquire_init(ticket, &reservation_ww_class);
+ ww_acquire_init(ticket, &reservation_ww_class);
retry:
list_for_each_entry(entry, list, head) {
struct ttm_buffer_object *bo = entry->bo;
@@ -140,17 +139,16 @@ retry:
if (entry->reserved)
continue;
- ret = ttm_bo_reserve_nolru(bo, true, (ticket == NULL), true,
- ticket);
+
+ ret = ttm_bo_reserve_nolru(bo, true, false, true, ticket);
if (ret == -EDEADLK) {
/* uh oh, we lost out, drop every reservation and try
* to only reserve this buffer, then start over if
* this succeeds.
*/
- BUG_ON(ticket == NULL);
spin_lock(&glob->lru_lock);
- ttm_eu_backoff_reservation_locked(list);
+ ttm_eu_backoff_reservation_locked(list, ticket);
spin_unlock(&glob->lru_lock);
ttm_eu_list_ref_sub(list);
ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
@@ -177,8 +175,7 @@ retry:
}
}
- if (ticket)
- ww_acquire_done(ticket);
+ ww_acquire_done(ticket);
spin_lock(&glob->lru_lock);
ttm_eu_del_from_lru_locked(list);
spin_unlock(&glob->lru_lock);
@@ -187,14 +184,12 @@ retry:
err:
spin_lock(&glob->lru_lock);
- ttm_eu_backoff_reservation_locked(list);
+ ttm_eu_backoff_reservation_locked(list, ticket);
spin_unlock(&glob->lru_lock);
ttm_eu_list_ref_sub(list);
err_fini:
- if (ticket) {
- ww_acquire_done(ticket);
- ww_acquire_fini(ticket);
- }
+ ww_acquire_done(ticket);
+ ww_acquire_fini(ticket);
return ret;
}
EXPORT_SYMBOL(ttm_eu_reserve_buffers);
@@ -229,8 +224,7 @@ void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
}
spin_unlock(&bdev->fence_lock);
spin_unlock(&glob->lru_lock);
- if (ticket)
- ww_acquire_fini(ticket);
+ ww_acquire_fini(ticket);
list_for_each_entry(entry, list, head) {
if (entry->old_sync_obj)
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c
index 6fe7b92..a868176 100644
--- a/drivers/gpu/drm/ttm/ttm_object.c
+++ b/drivers/gpu/drm/ttm/ttm_object.c
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright (c) 2009-2013 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,12 +26,6 @@
**************************************************************************/
/*
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
- *
- * While no substantial code is shared, the prime code is inspired by
- * drm_prime.c, with
- * Authors:
- * Dave Airlie <airlied@redhat.com>
- * Rob Clark <rob.clark@linaro.org>
*/
/** @file ttm_ref_object.c
*
@@ -40,7 +34,6 @@
* and release on file close.
*/
-
/**
* struct ttm_object_file
*
@@ -91,9 +84,6 @@ struct ttm_object_device {
struct drm_open_hash object_hash;
atomic_t object_count;
struct ttm_mem_global *mem_glob;
- struct dma_buf_ops ops;
- void (*dmabuf_release)(struct dma_buf *dma_buf);
- size_t dma_buf_size;
};
/**
@@ -126,8 +116,6 @@ struct ttm_ref_object {
struct ttm_object_file *tfile;
};
-static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf);
-
static inline struct ttm_object_file *
ttm_object_file_ref(struct ttm_object_file *tfile)
{
@@ -428,10 +416,9 @@ out_err:
}
EXPORT_SYMBOL(ttm_object_file_init);
-struct ttm_object_device *
-ttm_object_device_init(struct ttm_mem_global *mem_glob,
- unsigned int hash_order,
- const struct dma_buf_ops *ops)
+struct ttm_object_device *ttm_object_device_init(struct ttm_mem_global
+ *mem_glob,
+ unsigned int hash_order)
{
struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL);
int ret;
@@ -443,17 +430,10 @@ ttm_object_device_init(struct ttm_mem_global *mem_glob,
spin_lock_init(&tdev->object_lock);
atomic_set(&tdev->object_count, 0);
ret = drm_ht_create(&tdev->object_hash, hash_order);
- if (ret != 0)
- goto out_no_object_hash;
- tdev->ops = *ops;
- tdev->dmabuf_release = tdev->ops.release;
- tdev->ops.release = ttm_prime_dmabuf_release;
- tdev->dma_buf_size = ttm_round_pot(sizeof(struct dma_buf)) +
- ttm_round_pot(sizeof(struct file));
- return tdev;
+ if (likely(ret == 0))
+ return tdev;
-out_no_object_hash:
kfree(tdev);
return NULL;
}
@@ -472,225 +452,3 @@ void ttm_object_device_release(struct ttm_object_device **p_tdev)
kfree(tdev);
}
EXPORT_SYMBOL(ttm_object_device_release);
-
-/**
- * get_dma_buf_unless_doomed - get a dma_buf reference if possible.
- *
- * @dma_buf: Non-refcounted pointer to a struct dma-buf.
- *
- * Obtain a file reference from a lookup structure that doesn't refcount
- * the file, but synchronizes with its release method to make sure it has
- * not been freed yet. See for example kref_get_unless_zero documentation.
- * Returns true if refcounting succeeds, false otherwise.
- *
- * Nobody really wants this as a public API yet, so let it mature here
- * for some time...
- */
-static bool __must_check get_dma_buf_unless_doomed(struct dma_buf *dmabuf)
-{
- return atomic_long_inc_not_zero(&dmabuf->file->f_count) != 0L;
-}
-
-/**
- * ttm_prime_refcount_release - refcount release method for a prime object.
- *
- * @p_base: Pointer to ttm_base_object pointer.
- *
- * This is a wrapper that calls the refcount_release founction of the
- * underlying object. At the same time it cleans up the prime object.
- * This function is called when all references to the base object we
- * derive from are gone.
- */
-static void ttm_prime_refcount_release(struct ttm_base_object **p_base)
-{
- struct ttm_base_object *base = *p_base;
- struct ttm_prime_object *prime;
-
- *p_base = NULL;
- prime = container_of(base, struct ttm_prime_object, base);
- BUG_ON(prime->dma_buf != NULL);
- mutex_destroy(&prime->mutex);
- if (prime->refcount_release)
- prime->refcount_release(&base);
-}
-
-/**
- * ttm_prime_dmabuf_release - Release method for the dma-bufs we export
- *
- * @dma_buf:
- *
- * This function first calls the dma_buf release method the driver
- * provides. Then it cleans up our dma_buf pointer used for lookup,
- * and finally releases the reference the dma_buf has on our base
- * object.
- */
-static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf)
-{
- struct ttm_prime_object *prime =
- (struct ttm_prime_object *) dma_buf->priv;
- struct ttm_base_object *base = &prime->base;
- struct ttm_object_device *tdev = base->tfile->tdev;
-
- if (tdev->dmabuf_release)
- tdev->dmabuf_release(dma_buf);
- mutex_lock(&prime->mutex);
- if (prime->dma_buf == dma_buf)
- prime->dma_buf = NULL;
- mutex_unlock(&prime->mutex);
- ttm_mem_global_free(tdev->mem_glob, tdev->dma_buf_size);
- ttm_base_object_unref(&base);
-}
-
-/**
- * ttm_prime_fd_to_handle - Get a base object handle from a prime fd
- *
- * @tfile: A struct ttm_object_file identifying the caller.
- * @fd: The prime / dmabuf fd.
- * @handle: The returned handle.
- *
- * This function returns a handle to an object that previously exported
- * a dma-buf. Note that we don't handle imports yet, because we simply
- * have no consumers of that implementation.
- */
-int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
- int fd, u32 *handle)
-{
- struct ttm_object_device *tdev = tfile->tdev;
- struct dma_buf *dma_buf;
- struct ttm_prime_object *prime;
- struct ttm_base_object *base;
- int ret;
-
- dma_buf = dma_buf_get(fd);
- if (IS_ERR(dma_buf))
- return PTR_ERR(dma_buf);
-
- if (dma_buf->ops != &tdev->ops)
- return -ENOSYS;
-
- prime = (struct ttm_prime_object *) dma_buf->priv;
- base = &prime->base;
- *handle = base->hash.key;
- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
-
- dma_buf_put(dma_buf);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(ttm_prime_fd_to_handle);
-
-/**
- * ttm_prime_handle_to_fd - Return a dma_buf fd from a ttm prime object
- *
- * @tfile: Struct ttm_object_file identifying the caller.
- * @handle: Handle to the object we're exporting from.
- * @flags: flags for dma-buf creation. We just pass them on.
- * @prime_fd: The returned file descriptor.
- *
- */
-int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
- uint32_t handle, uint32_t flags,
- int *prime_fd)
-{
- struct ttm_object_device *tdev = tfile->tdev;
- struct ttm_base_object *base;
- struct dma_buf *dma_buf;
- struct ttm_prime_object *prime;
- int ret;
-
- base = ttm_base_object_lookup(tfile, handle);
- if (unlikely(base == NULL ||
- base->object_type != ttm_prime_type)) {
- ret = -ENOENT;
- goto out_unref;
- }
-
- prime = container_of(base, struct ttm_prime_object, base);
- if (unlikely(!base->shareable)) {
- ret = -EPERM;
- goto out_unref;
- }
-
- ret = mutex_lock_interruptible(&prime->mutex);
- if (unlikely(ret != 0)) {
- ret = -ERESTARTSYS;
- goto out_unref;
- }
-
- dma_buf = prime->dma_buf;
- if (!dma_buf || !get_dma_buf_unless_doomed(dma_buf)) {
-
- /*
- * Need to create a new dma_buf, with memory accounting.
- */
- ret = ttm_mem_global_alloc(tdev->mem_glob, tdev->dma_buf_size,
- false, true);
- if (unlikely(ret != 0)) {
- mutex_unlock(&prime->mutex);
- goto out_unref;
- }
-
- dma_buf = dma_buf_export(prime, &tdev->ops,
- prime->size, flags);
- if (IS_ERR(dma_buf)) {
- ret = PTR_ERR(dma_buf);
- ttm_mem_global_free(tdev->mem_glob,
- tdev->dma_buf_size);
- mutex_unlock(&prime->mutex);
- goto out_unref;
- }
-
- /*
- * dma_buf has taken the base object reference
- */
- base = NULL;
- prime->dma_buf = dma_buf;
- }
- mutex_unlock(&prime->mutex);
-
- ret = dma_buf_fd(dma_buf, flags);
- if (ret >= 0) {
- *prime_fd = ret;
- ret = 0;
- } else
- dma_buf_put(dma_buf);
-
-out_unref:
- if (base)
- ttm_base_object_unref(&base);
- return ret;
-}
-EXPORT_SYMBOL_GPL(ttm_prime_handle_to_fd);
-
-/**
- * ttm_prime_object_init - Initialize a ttm_prime_object
- *
- * @tfile: struct ttm_object_file identifying the caller
- * @size: The size of the dma_bufs we export.
- * @prime: The object to be initialized.
- * @shareable: See ttm_base_object_init
- * @type: See ttm_base_object_init
- * @refcount_release: See ttm_base_object_init
- * @ref_obj_release: See ttm_base_object_init
- *
- * Initializes an object which is compatible with the drm_prime model
- * for data sharing between processes and devices.
- */
-int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size,
- struct ttm_prime_object *prime, bool shareable,
- enum ttm_object_type type,
- void (*refcount_release) (struct ttm_base_object **),
- void (*ref_obj_release) (struct ttm_base_object *,
- enum ttm_ref_type ref_type))
-{
- mutex_init(&prime->mutex);
- prime->size = PAGE_ALIGN(size);
- prime->real_type = type;
- prime->dma_buf = NULL;
- prime->refcount_release = refcount_release;
- return ttm_base_object_init(tfile, &prime->base, shareable,
- ttm_prime_type,
- ttm_prime_refcount_release,
- ref_obj_release);
-}
-EXPORT_SYMBOL(ttm_prime_object_init);
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index fb8259f..7957bee 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -33,7 +33,6 @@
* when freed).
*/
-#if defined(CONFIG_SWIOTLB) || defined(CONFIG_INTEL_IOMMU)
#define pr_fmt(fmt) "[TTM] " fmt
#include <linux/dma-mapping.h>
@@ -1143,5 +1142,3 @@ int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data)
return 0;
}
EXPORT_SYMBOL_GPL(ttm_dma_page_alloc_debugfs);
-
-#endif
diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig
index f025286..6222af1 100644
--- a/drivers/gpu/drm/udl/Kconfig
+++ b/drivers/gpu/drm/udl/Kconfig
@@ -8,7 +8,6 @@ config DRM_UDL
select FB_SYS_IMAGEBLIT
select FB_DEFERRED_IO
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
help
This is a KMS driver for the USB displaylink video adapters.
Say M/Y to add support for these devices via drm/kms interfaces.
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 3ddd6cd..7650dc0 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -77,6 +77,7 @@ static struct drm_driver driver = {
.unload = udl_driver_unload,
/* gem hooks */
+ .gem_init_object = udl_gem_init_object,
.gem_free_object = udl_gem_free_object,
.gem_vm_ops = &udl_gem_vm_ops,
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 1fbf7b3..56aec94 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -115,6 +115,7 @@ int udl_dumb_create(struct drm_file *file_priv,
int udl_gem_mmap(struct drm_file *file_priv, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
+int udl_gem_init_object(struct drm_gem_object *obj);
void udl_gem_free_object(struct drm_gem_object *gem_obj);
struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev,
size_t size);
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
index 8d67b94..8bf6461 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
@@ -107,6 +107,13 @@ int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
}
+int udl_gem_init_object(struct drm_gem_object *obj)
+{
+ BUG();
+
+ return 0;
+}
+
static int udl_gem_get_pages(struct udl_gem_object *obj, gfp_t gfpmask)
{
struct page **pages;
@@ -125,12 +132,6 @@ static int udl_gem_get_pages(struct udl_gem_object *obj, gfp_t gfpmask)
static void udl_gem_put_pages(struct udl_gem_object *obj)
{
- if (obj->base.import_attach) {
- drm_free_large(obj->pages);
- obj->pages = NULL;
- return;
- }
-
drm_gem_put_pages(&obj->base, obj->pages, false, false);
obj->pages = NULL;
}
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index 9278891..7e3ad87 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -79,7 +79,7 @@ int via_final_context(struct drm_device *dev, int context)
/* Linux specific until context tracking code gets ported to BSD */
/* Last context, perform cleanup */
- if (list_is_singular(&dev->ctxlist) && dev->dev_private) {
+ if (dev->ctx_count == 1 && dev->dev_private) {
DRM_DEBUG("Last Context\n");
drm_irq_uninstall(dev);
via_cleanup_futex(dev_priv);
diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index 9f8b690..2cc6cd9 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -6,6 +6,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \
vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.o \
- vmwgfx_surface.o vmwgfx_prime.o
+ vmwgfx_surface.o
obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
index 0489c61..96dc84d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
@@ -141,374 +141,35 @@ struct ttm_placement vmw_srf_placement = {
};
struct vmw_ttm_tt {
- struct ttm_dma_tt dma_ttm;
+ struct ttm_tt ttm;
struct vmw_private *dev_priv;
int gmr_id;
- struct sg_table sgt;
- struct vmw_sg_table vsgt;
- uint64_t sg_alloc_size;
- bool mapped;
};
-const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt);
-
-/**
- * Helper functions to advance a struct vmw_piter iterator.
- *
- * @viter: Pointer to the iterator.
- *
- * These functions return false if past the end of the list,
- * true otherwise. Functions are selected depending on the current
- * DMA mapping mode.
- */
-static bool __vmw_piter_non_sg_next(struct vmw_piter *viter)
-{
- return ++(viter->i) < viter->num_pages;
-}
-
-static bool __vmw_piter_sg_next(struct vmw_piter *viter)
-{
- return __sg_page_iter_next(&viter->iter);
-}
-
-
-/**
- * Helper functions to return a pointer to the current page.
- *
- * @viter: Pointer to the iterator
- *
- * These functions return a pointer to the page currently
- * pointed to by @viter. Functions are selected depending on the
- * current mapping mode.
- */
-static struct page *__vmw_piter_non_sg_page(struct vmw_piter *viter)
-{
- return viter->pages[viter->i];
-}
-
-static struct page *__vmw_piter_sg_page(struct vmw_piter *viter)
-{
- return sg_page_iter_page(&viter->iter);
-}
-
-
-/**
- * Helper functions to return the DMA address of the current page.
- *
- * @viter: Pointer to the iterator
- *
- * These functions return the DMA address of the page currently
- * pointed to by @viter. Functions are selected depending on the
- * current mapping mode.
- */
-static dma_addr_t __vmw_piter_phys_addr(struct vmw_piter *viter)
-{
- return page_to_phys(viter->pages[viter->i]);
-}
-
-static dma_addr_t __vmw_piter_dma_addr(struct vmw_piter *viter)
-{
- return viter->addrs[viter->i];
-}
-
-static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter)
-{
- return sg_page_iter_dma_address(&viter->iter);
-}
-
-
-/**
- * vmw_piter_start - Initialize a struct vmw_piter.
- *
- * @viter: Pointer to the iterator to initialize
- * @vsgt: Pointer to a struct vmw_sg_table to initialize from
- *
- * Note that we're following the convention of __sg_page_iter_start, so that
- * the iterator doesn't point to a valid page after initialization; it has
- * to be advanced one step first.
- */
-void vmw_piter_start(struct vmw_piter *viter, const struct vmw_sg_table *vsgt,
- unsigned long p_offset)
-{
- viter->i = p_offset - 1;
- viter->num_pages = vsgt->num_pages;
- switch (vsgt->mode) {
- case vmw_dma_phys:
- viter->next = &__vmw_piter_non_sg_next;
- viter->dma_address = &__vmw_piter_phys_addr;
- viter->page = &__vmw_piter_non_sg_page;
- viter->pages = vsgt->pages;
- break;
- case vmw_dma_alloc_coherent:
- viter->next = &__vmw_piter_non_sg_next;
- viter->dma_address = &__vmw_piter_dma_addr;
- viter->page = &__vmw_piter_non_sg_page;
- viter->addrs = vsgt->addrs;
- break;
- case vmw_dma_map_populate:
- case vmw_dma_map_bind:
- viter->next = &__vmw_piter_sg_next;
- viter->dma_address = &__vmw_piter_sg_addr;
- viter->page = &__vmw_piter_sg_page;
- __sg_page_iter_start(&viter->iter, vsgt->sgt->sgl,
- vsgt->sgt->orig_nents, p_offset);
- break;
- default:
- BUG();
- }
-}
-
-/**
- * vmw_ttm_unmap_from_dma - unmap device addresses previsouly mapped for
- * TTM pages
- *
- * @vmw_tt: Pointer to a struct vmw_ttm_backend
- *
- * Used to free dma mappings previously mapped by vmw_ttm_map_for_dma.
- */
-static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
-{
- struct device *dev = vmw_tt->dev_priv->dev->dev;
-
- dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents,
- DMA_BIDIRECTIONAL);
- vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
-}
-
-/**
- * vmw_ttm_map_for_dma - map TTM pages to get device addresses
- *
- * @vmw_tt: Pointer to a struct vmw_ttm_backend
- *
- * This function is used to get device addresses from the kernel DMA layer.
- * However, it's violating the DMA API in that when this operation has been
- * performed, it's illegal for the CPU to write to the pages without first
- * unmapping the DMA mappings, or calling dma_sync_sg_for_cpu(). It is
- * therefore only legal to call this function if we know that the function
- * dma_sync_sg_for_cpu() is a NOP, and dma_sync_sg_for_device() is at most
- * a CPU write buffer flush.
- */
-static int vmw_ttm_map_for_dma(struct vmw_ttm_tt *vmw_tt)
-{
- struct device *dev = vmw_tt->dev_priv->dev->dev;
- int ret;
-
- ret = dma_map_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents,
- DMA_BIDIRECTIONAL);
- if (unlikely(ret == 0))
- return -ENOMEM;
-
- vmw_tt->sgt.nents = ret;
-
- return 0;
-}
-
-/**
- * vmw_ttm_map_dma - Make sure TTM pages are visible to the device
- *
- * @vmw_tt: Pointer to a struct vmw_ttm_tt
- *
- * Select the correct function for and make sure the TTM pages are
- * visible to the device. Allocate storage for the device mappings.
- * If a mapping has already been performed, indicated by the storage
- * pointer being non NULL, the function returns success.
- */
-static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
-{
- struct vmw_private *dev_priv = vmw_tt->dev_priv;
- struct ttm_mem_global *glob = vmw_mem_glob(dev_priv);
- struct vmw_sg_table *vsgt = &vmw_tt->vsgt;
- struct vmw_piter iter;
- dma_addr_t old;
- int ret = 0;
- static size_t sgl_size;
- static size_t sgt_size;
-
- if (vmw_tt->mapped)
- return 0;
-
- vsgt->mode = dev_priv->map_mode;
- vsgt->pages = vmw_tt->dma_ttm.ttm.pages;
- vsgt->num_pages = vmw_tt->dma_ttm.ttm.num_pages;
- vsgt->addrs = vmw_tt->dma_ttm.dma_address;
- vsgt->sgt = &vmw_tt->sgt;
-
- switch (dev_priv->map_mode) {
- case vmw_dma_map_bind:
- case vmw_dma_map_populate:
- if (unlikely(!sgl_size)) {
- sgl_size = ttm_round_pot(sizeof(struct scatterlist));
- sgt_size = ttm_round_pot(sizeof(struct sg_table));
- }
- vmw_tt->sg_alloc_size = sgt_size + sgl_size * vsgt->num_pages;
- ret = ttm_mem_global_alloc(glob, vmw_tt->sg_alloc_size, false,
- true);
- if (unlikely(ret != 0))
- return ret;
-
- ret = sg_alloc_table_from_pages(&vmw_tt->sgt, vsgt->pages,
- vsgt->num_pages, 0,
- (unsigned long)
- vsgt->num_pages << PAGE_SHIFT,
- GFP_KERNEL);
- if (unlikely(ret != 0))
- goto out_sg_alloc_fail;
-
- if (vsgt->num_pages > vmw_tt->sgt.nents) {
- uint64_t over_alloc =
- sgl_size * (vsgt->num_pages -
- vmw_tt->sgt.nents);
-
- ttm_mem_global_free(glob, over_alloc);
- vmw_tt->sg_alloc_size -= over_alloc;
- }
-
- ret = vmw_ttm_map_for_dma(vmw_tt);
- if (unlikely(ret != 0))
- goto out_map_fail;
-
- break;
- default:
- break;
- }
-
- old = ~((dma_addr_t) 0);
- vmw_tt->vsgt.num_regions = 0;
- for (vmw_piter_start(&iter, vsgt, 0); vmw_piter_next(&iter);) {
- dma_addr_t cur = vmw_piter_dma_addr(&iter);
-
- if (cur != old + PAGE_SIZE)
- vmw_tt->vsgt.num_regions++;
- old = cur;
- }
-
- vmw_tt->mapped = true;
- return 0;
-
-out_map_fail:
- sg_free_table(vmw_tt->vsgt.sgt);
- vmw_tt->vsgt.sgt = NULL;
-out_sg_alloc_fail:
- ttm_mem_global_free(glob, vmw_tt->sg_alloc_size);
- return ret;
-}
-
-/**
- * vmw_ttm_unmap_dma - Tear down any TTM page device mappings
- *
- * @vmw_tt: Pointer to a struct vmw_ttm_tt
- *
- * Tear down any previously set up device DMA mappings and free
- * any storage space allocated for them. If there are no mappings set up,
- * this function is a NOP.
- */
-static void vmw_ttm_unmap_dma(struct vmw_ttm_tt *vmw_tt)
-{
- struct vmw_private *dev_priv = vmw_tt->dev_priv;
-
- if (!vmw_tt->vsgt.sgt)
- return;
-
- switch (dev_priv->map_mode) {
- case vmw_dma_map_bind:
- case vmw_dma_map_populate:
- vmw_ttm_unmap_from_dma(vmw_tt);
- sg_free_table(vmw_tt->vsgt.sgt);
- vmw_tt->vsgt.sgt = NULL;
- ttm_mem_global_free(vmw_mem_glob(dev_priv),
- vmw_tt->sg_alloc_size);
- break;
- default:
- break;
- }
- vmw_tt->mapped = false;
-}
-
static int vmw_ttm_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
{
- struct vmw_ttm_tt *vmw_be =
- container_of(ttm, struct vmw_ttm_tt, dma_ttm.ttm);
- int ret;
-
- ret = vmw_ttm_map_dma(vmw_be);
- if (unlikely(ret != 0))
- return ret;
+ struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, ttm);
vmw_be->gmr_id = bo_mem->start;
- return vmw_gmr_bind(vmw_be->dev_priv, &vmw_be->vsgt,
+ return vmw_gmr_bind(vmw_be->dev_priv, ttm->pages,
ttm->num_pages, vmw_be->gmr_id);
}
static int vmw_ttm_unbind(struct ttm_tt *ttm)
{
- struct vmw_ttm_tt *vmw_be =
- container_of(ttm, struct vmw_ttm_tt, dma_ttm.ttm);
+ struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, ttm);
vmw_gmr_unbind(vmw_be->dev_priv, vmw_be->gmr_id);
-
- if (vmw_be->dev_priv->map_mode == vmw_dma_map_bind)
- vmw_ttm_unmap_dma(vmw_be);
-
return 0;
}
static void vmw_ttm_destroy(struct ttm_tt *ttm)
{
- struct vmw_ttm_tt *vmw_be =
- container_of(ttm, struct vmw_ttm_tt, dma_ttm.ttm);
-
- vmw_ttm_unmap_dma(vmw_be);
- if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent)
- ttm_dma_tt_fini(&vmw_be->dma_ttm);
- else
- ttm_tt_fini(ttm);
- kfree(vmw_be);
-}
+ struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, ttm);
-static int vmw_ttm_populate(struct ttm_tt *ttm)
-{
- struct vmw_ttm_tt *vmw_tt =
- container_of(ttm, struct vmw_ttm_tt, dma_ttm.ttm);
- struct vmw_private *dev_priv = vmw_tt->dev_priv;
- struct ttm_mem_global *glob = vmw_mem_glob(dev_priv);
- int ret;
-
- if (ttm->state != tt_unpopulated)
- return 0;
-
- if (dev_priv->map_mode == vmw_dma_alloc_coherent) {
- size_t size =
- ttm_round_pot(ttm->num_pages * sizeof(dma_addr_t));
- ret = ttm_mem_global_alloc(glob, size, false, true);
- if (unlikely(ret != 0))
- return ret;
-
- ret = ttm_dma_populate(&vmw_tt->dma_ttm, dev_priv->dev->dev);
- if (unlikely(ret != 0))
- ttm_mem_global_free(glob, size);
- } else
- ret = ttm_pool_populate(ttm);
-
- return ret;
-}
-
-static void vmw_ttm_unpopulate(struct ttm_tt *ttm)
-{
- struct vmw_ttm_tt *vmw_tt = container_of(ttm, struct vmw_ttm_tt,
- dma_ttm.ttm);
- struct vmw_private *dev_priv = vmw_tt->dev_priv;
- struct ttm_mem_global *glob = vmw_mem_glob(dev_priv);
-
- vmw_ttm_unmap_dma(vmw_tt);
- if (dev_priv->map_mode == vmw_dma_alloc_coherent) {
- size_t size =
- ttm_round_pot(ttm->num_pages * sizeof(dma_addr_t));
-
- ttm_dma_unpopulate(&vmw_tt->dma_ttm, dev_priv->dev->dev);
- ttm_mem_global_free(glob, size);
- } else
- ttm_pool_unpopulate(ttm);
+ ttm_tt_fini(ttm);
+ kfree(vmw_be);
}
static struct ttm_backend_func vmw_ttm_func = {
@@ -522,28 +183,20 @@ struct ttm_tt *vmw_ttm_tt_create(struct ttm_bo_device *bdev,
struct page *dummy_read_page)
{
struct vmw_ttm_tt *vmw_be;
- int ret;
- vmw_be = kzalloc(sizeof(*vmw_be), GFP_KERNEL);
+ vmw_be = kmalloc(sizeof(*vmw_be), GFP_KERNEL);
if (!vmw_be)
return NULL;
- vmw_be->dma_ttm.ttm.func = &vmw_ttm_func;
+ vmw_be->ttm.func = &vmw_ttm_func;
vmw_be->dev_priv = container_of(bdev, struct vmw_private, bdev);
- if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent)
- ret = ttm_dma_tt_init(&vmw_be->dma_ttm, bdev, size, page_flags,
- dummy_read_page);
- else
- ret = ttm_tt_init(&vmw_be->dma_ttm.ttm, bdev, size, page_flags,
- dummy_read_page);
- if (unlikely(ret != 0))
- goto out_no_init;
-
- return &vmw_be->dma_ttm.ttm;
-out_no_init:
- kfree(vmw_be);
- return NULL;
+ if (ttm_tt_init(&vmw_be->ttm, bdev, size, page_flags, dummy_read_page)) {
+ kfree(vmw_be);
+ return NULL;
+ }
+
+ return &vmw_be->ttm;
}
int vmw_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
@@ -679,8 +332,8 @@ static int vmw_sync_obj_wait(void *sync_obj, bool lazy, bool interruptible)
struct ttm_bo_driver vmw_bo_driver = {
.ttm_tt_create = &vmw_ttm_tt_create,
- .ttm_tt_populate = &vmw_ttm_populate,
- .ttm_tt_unpopulate = &vmw_ttm_unpopulate,
+ .ttm_tt_populate = &ttm_pool_populate,
+ .ttm_tt_unpopulate = &ttm_pool_unpopulate,
.invalidate_caches = vmw_invalidate_caches,
.init_mem_type = vmw_init_mem_type,
.evict_flags = vmw_evict_flags,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index c7a5496..0508f93 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -32,7 +32,6 @@
#include <drm/ttm/ttm_bo_driver.h>
#include <drm/ttm/ttm_object.h>
#include <drm/ttm/ttm_module.h>
-#include <linux/dma_remapping.h>
#define VMWGFX_DRIVER_NAME "vmwgfx"
#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices"
@@ -186,9 +185,6 @@ static struct pci_device_id vmw_pci_id_list[] = {
MODULE_DEVICE_TABLE(pci, vmw_pci_id_list);
static int enable_fbdev = IS_ENABLED(CONFIG_DRM_VMWGFX_FBCON);
-static int vmw_force_iommu;
-static int vmw_restrict_iommu;
-static int vmw_force_coherent;
static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
static void vmw_master_init(struct vmw_master *);
@@ -197,13 +193,6 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
module_param_named(enable_fbdev, enable_fbdev, int, 0600);
-MODULE_PARM_DESC(force_dma_api, "Force using the DMA API for TTM pages");
-module_param_named(force_dma_api, vmw_force_iommu, int, 0600);
-MODULE_PARM_DESC(restrict_iommu, "Try to limit IOMMU usage for TTM pages");
-module_param_named(restrict_iommu, vmw_restrict_iommu, int, 0600);
-MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
-module_param_named(force_coherent, vmw_force_coherent, int, 0600);
-
static void vmw_print_capabilities(uint32_t capabilities)
{
@@ -438,85 +427,12 @@ static void vmw_get_initial_size(struct vmw_private *dev_priv)
dev_priv->initial_height = height;
}
-/**
- * vmw_dma_select_mode - Determine how DMA mappings should be set up for this
- * system.
- *
- * @dev_priv: Pointer to a struct vmw_private
- *
- * This functions tries to determine the IOMMU setup and what actions
- * need to be taken by the driver to make system pages visible to the
- * device.
- * If this function decides that DMA is not possible, it returns -EINVAL.
- * The driver may then try to disable features of the device that require
- * DMA.
- */
-static int vmw_dma_select_mode(struct vmw_private *dev_priv)
-{
- static const char *names[vmw_dma_map_max] = {
- [vmw_dma_phys] = "Using physical TTM page addresses.",
- [vmw_dma_alloc_coherent] = "Using coherent TTM pages.",
- [vmw_dma_map_populate] = "Keeping DMA mappings.",
- [vmw_dma_map_bind] = "Giving up DMA mappings early."};
-#ifdef CONFIG_X86
- const struct dma_map_ops *dma_ops = get_dma_ops(dev_priv->dev->dev);
-
-#ifdef CONFIG_INTEL_IOMMU
- if (intel_iommu_enabled) {
- dev_priv->map_mode = vmw_dma_map_populate;
- goto out_fixup;
- }
-#endif
-
- if (!(vmw_force_iommu || vmw_force_coherent)) {
- dev_priv->map_mode = vmw_dma_phys;
- DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]);
- return 0;
- }
-
- dev_priv->map_mode = vmw_dma_map_populate;
-
- if (dma_ops->sync_single_for_cpu)
- dev_priv->map_mode = vmw_dma_alloc_coherent;
-#ifdef CONFIG_SWIOTLB
- if (swiotlb_nr_tbl() == 0)
- dev_priv->map_mode = vmw_dma_map_populate;
-#endif
-
-#ifdef CONFIG_INTEL_IOMMU
-out_fixup:
-#endif
- if (dev_priv->map_mode == vmw_dma_map_populate &&
- vmw_restrict_iommu)
- dev_priv->map_mode = vmw_dma_map_bind;
-
- if (vmw_force_coherent)
- dev_priv->map_mode = vmw_dma_alloc_coherent;
-
-#if !defined(CONFIG_SWIOTLB) && !defined(CONFIG_INTEL_IOMMU)
- /*
- * No coherent page pool
- */
- if (dev_priv->map_mode == vmw_dma_alloc_coherent)
- return -EINVAL;
-#endif
-
-#else /* CONFIG_X86 */
- dev_priv->map_mode = vmw_dma_map_populate;
-#endif /* CONFIG_X86 */
-
- DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]);
-
- return 0;
-}
-
static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
{
struct vmw_private *dev_priv;
int ret;
uint32_t svga_id;
enum vmw_res_type i;
- bool refuse_dma = false;
dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
if (unlikely(dev_priv == NULL)) {
@@ -565,11 +481,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
}
dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES);
- ret = vmw_dma_select_mode(dev_priv);
- if (unlikely(ret != 0)) {
- DRM_INFO("Restricting capabilities due to IOMMU setup.\n");
- refuse_dma = true;
- }
dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE);
dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE);
@@ -647,9 +558,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
}
dev_priv->has_gmr = true;
- if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) ||
- refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR,
- dev_priv->max_gmr_ids) != 0) {
+ if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR,
+ dev_priv->max_gmr_ids) != 0) {
DRM_INFO("No GMR memory available. "
"Graphics memory resources are very limited.\n");
dev_priv->has_gmr = false;
@@ -677,7 +587,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
}
dev_priv->tdev = ttm_object_device_init
- (dev_priv->mem_global_ref.object, 12, &vmw_prime_dmabuf_ops);
+ (dev_priv->mem_global_ref.object, 12);
if (unlikely(dev_priv->tdev == NULL)) {
DRM_ERROR("Unable to initialize TTM object management.\n");
@@ -1210,7 +1120,7 @@ static const struct file_operations vmwgfx_driver_fops = {
static struct drm_driver driver = {
.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
- DRIVER_MODESET | DRIVER_PRIME,
+ DRIVER_MODESET,
.load = vmw_driver_load,
.unload = vmw_driver_unload,
.lastclose = vmw_lastclose,
@@ -1235,9 +1145,6 @@ static struct drm_driver driver = {
.dumb_map_offset = vmw_dumb_map_offset,
.dumb_destroy = vmw_dumb_destroy,
- .prime_fd_to_handle = vmw_prime_fd_to_handle,
- .prime_handle_to_fd = vmw_prime_handle_to_fd,
-
.fops = &vmwgfx_driver_fops,
.name = VMWGFX_DRIVER_NAME,
.desc = VMWGFX_DRIVER_DESC,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 20890ad..150ec64 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -177,58 +177,6 @@ struct vmw_res_cache_entry {
struct vmw_resource_val_node *node;
};
-/**
- * enum vmw_dma_map_mode - indicate how to perform TTM page dma mappings.
- */
-enum vmw_dma_map_mode {
- vmw_dma_phys, /* Use physical page addresses */
- vmw_dma_alloc_coherent, /* Use TTM coherent pages */
- vmw_dma_map_populate, /* Unmap from DMA just after unpopulate */
- vmw_dma_map_bind, /* Unmap from DMA just before unbind */
- vmw_dma_map_max
-};
-
-/**
- * struct vmw_sg_table - Scatter/gather table for binding, with additional
- * device-specific information.
- *
- * @sgt: Pointer to a struct sg_table with binding information
- * @num_regions: Number of regions with device-address contigous pages
- */
-struct vmw_sg_table {
- enum vmw_dma_map_mode mode;
- struct page **pages;
- const dma_addr_t *addrs;
- struct sg_table *sgt;
- unsigned long num_regions;
- unsigned long num_pages;
-};
-
-/**
- * struct vmw_piter - Page iterator that iterates over a list of pages
- * and DMA addresses that could be either a scatter-gather list or
- * arrays
- *
- * @pages: Array of page pointers to the pages.
- * @addrs: DMA addresses to the pages if coherent pages are used.
- * @iter: Scatter-gather page iterator. Current position in SG list.
- * @i: Current position in arrays.
- * @num_pages: Number of pages total.
- * @next: Function to advance the iterator. Returns false if past the list
- * of pages, true otherwise.
- * @dma_address: Function to return the DMA address of the current page.
- */
-struct vmw_piter {
- struct page **pages;
- const dma_addr_t *addrs;
- struct sg_page_iter iter;
- unsigned long i;
- unsigned long num_pages;
- bool (*next)(struct vmw_piter *);
- dma_addr_t (*dma_address)(struct vmw_piter *);
- struct page *(*page)(struct vmw_piter *);
-};
-
struct vmw_sw_context{
struct drm_open_hash res_ht;
bool res_ht_initialized;
@@ -410,11 +358,6 @@ struct vmw_private {
struct list_head res_lru[vmw_res_max];
uint32_t used_memory_size;
-
- /*
- * DMA mapping stuff.
- */
- enum vmw_dma_map_mode map_mode;
};
static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res)
@@ -462,7 +405,7 @@ void vmw_3d_resource_dec(struct vmw_private *dev_priv, bool hide_svga);
*/
extern int vmw_gmr_bind(struct vmw_private *dev_priv,
- const struct vmw_sg_table *vsgt,
+ struct page *pages[],
unsigned long num_pages,
int gmr_id);
extern void vmw_gmr_unbind(struct vmw_private *dev_priv, int gmr_id);
@@ -615,7 +558,6 @@ extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma);
* TTM buffer object driver - vmwgfx_buffer.c
*/
-extern const size_t vmw_tt_size;
extern struct ttm_placement vmw_vram_placement;
extern struct ttm_placement vmw_vram_ne_placement;
extern struct ttm_placement vmw_vram_sys_placement;
@@ -626,45 +568,6 @@ extern struct ttm_placement vmw_evictable_placement;
extern struct ttm_placement vmw_srf_placement;
extern struct ttm_bo_driver vmw_bo_driver;
extern int vmw_dma_quiescent(struct drm_device *dev);
-extern void vmw_piter_start(struct vmw_piter *viter,
- const struct vmw_sg_table *vsgt,
- unsigned long p_offs);
-
-/**
- * vmw_piter_next - Advance the iterator one page.
- *
- * @viter: Pointer to the iterator to advance.
- *
- * Returns false if past the list of pages, true otherwise.
- */
-static inline bool vmw_piter_next(struct vmw_piter *viter)
-{
- return viter->next(viter);
-}
-
-/**
- * vmw_piter_dma_addr - Return the DMA address of the current page.
- *
- * @viter: Pointer to the iterator
- *
- * Returns the DMA address of the page pointed to by @viter.
- */
-static inline dma_addr_t vmw_piter_dma_addr(struct vmw_piter *viter)
-{
- return viter->dma_address(viter);
-}
-
-/**
- * vmw_piter_page - Return a pointer to the current page.
- *
- * @viter: Pointer to the iterator
- *
- * Returns the DMA address of the page pointed to by @viter.
- */
-static inline struct page *vmw_piter_page(struct vmw_piter *viter)
-{
- return viter->page(viter);
-}
/**
* Command submission - vmwgfx_execbuf.c
@@ -820,20 +723,6 @@ int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv);
extern const struct ttm_mem_type_manager_func vmw_gmrid_manager_func;
/**
- * Prime - vmwgfx_prime.c
- */
-
-extern const struct dma_buf_ops vmw_prime_dmabuf_ops;
-extern int vmw_prime_fd_to_handle(struct drm_device *dev,
- struct drm_file *file_priv,
- int fd, u32 *handle);
-extern int vmw_prime_handle_to_fd(struct drm_device *dev,
- struct drm_file *file_priv,
- uint32_t handle, uint32_t flags,
- int *prime_fd);
-
-
-/**
* Inline helper functions
*/
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
index 6ef0b03..1a0bf07 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
@@ -32,11 +32,9 @@
#define VMW_PPN_SIZE (sizeof(unsigned long))
/* A future safe maximum remap size. */
#define VMW_PPN_PER_REMAP ((31 * 1024) / VMW_PPN_SIZE)
-#define DMA_ADDR_INVALID ((dma_addr_t) 0)
-#define DMA_PAGE_INVALID 0UL
static int vmw_gmr2_bind(struct vmw_private *dev_priv,
- struct vmw_piter *iter,
+ struct page *pages[],
unsigned long num_pages,
int gmr_id)
{
@@ -83,13 +81,11 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv,
for (i = 0; i < nr; ++i) {
if (VMW_PPN_SIZE <= 4)
- *cmd = vmw_piter_dma_addr(iter) >> PAGE_SHIFT;
+ *cmd = page_to_pfn(*pages++);
else
- *((uint64_t *)cmd) = vmw_piter_dma_addr(iter) >>
- PAGE_SHIFT;
+ *((uint64_t *)cmd) = page_to_pfn(*pages++);
cmd += VMW_PPN_SIZE / sizeof(*cmd);
- vmw_piter_next(iter);
}
num_pages -= nr;
@@ -124,56 +120,22 @@ static void vmw_gmr2_unbind(struct vmw_private *dev_priv,
vmw_fifo_commit(dev_priv, define_size);
}
-
-static void vmw_gmr_free_descriptors(struct device *dev, dma_addr_t desc_dma,
- struct list_head *desc_pages)
-{
- struct page *page, *next;
- struct svga_guest_mem_descriptor *page_virtual;
- unsigned int desc_per_page = PAGE_SIZE /
- sizeof(struct svga_guest_mem_descriptor) - 1;
-
- if (list_empty(desc_pages))
- return;
-
- list_for_each_entry_safe(page, next, desc_pages, lru) {
- list_del_init(&page->lru);
-
- if (likely(desc_dma != DMA_ADDR_INVALID)) {
- dma_unmap_page(dev, desc_dma, PAGE_SIZE,
- DMA_TO_DEVICE);
- }
-
- page_virtual = kmap_atomic(page);
- desc_dma = (dma_addr_t)
- le32_to_cpu(page_virtual[desc_per_page].ppn) <<
- PAGE_SHIFT;
- kunmap_atomic(page_virtual);
-
- __free_page(page);
- }
-}
-
/**
* FIXME: Adjust to the ttm lowmem / highmem storage to minimize
* the number of used descriptors.
- *
*/
-static int vmw_gmr_build_descriptors(struct device *dev,
- struct list_head *desc_pages,
- struct vmw_piter *iter,
- unsigned long num_pages,
- dma_addr_t *first_dma)
+static int vmw_gmr_build_descriptors(struct list_head *desc_pages,
+ struct page *pages[],
+ unsigned long num_pages)
{
- struct page *page;
+ struct page *page, *next;
struct svga_guest_mem_descriptor *page_virtual = NULL;
struct svga_guest_mem_descriptor *desc_virtual = NULL;
unsigned int desc_per_page;
unsigned long prev_pfn;
unsigned long pfn;
int ret;
- dma_addr_t desc_dma;
desc_per_page = PAGE_SIZE /
sizeof(struct svga_guest_mem_descriptor) - 1;
@@ -186,12 +148,23 @@ static int vmw_gmr_build_descriptors(struct device *dev,
}
list_add_tail(&page->lru, desc_pages);
+
+ /*
+ * Point previous page terminating descriptor to this
+ * page before unmapping it.
+ */
+
+ if (likely(page_virtual != NULL)) {
+ desc_virtual->ppn = page_to_pfn(page);
+ kunmap_atomic(page_virtual);
+ }
+
page_virtual = kmap_atomic(page);
desc_virtual = page_virtual - 1;
prev_pfn = ~(0UL);
while (likely(num_pages != 0)) {
- pfn = vmw_piter_dma_addr(iter) >> PAGE_SHIFT;
+ pfn = page_to_pfn(*pages);
if (pfn != prev_pfn + 1) {
@@ -208,82 +181,104 @@ static int vmw_gmr_build_descriptors(struct device *dev,
}
prev_pfn = pfn;
--num_pages;
- vmw_piter_next(iter);
+ ++pages;
}
- (++desc_virtual)->ppn = DMA_PAGE_INVALID;
+ (++desc_virtual)->ppn = cpu_to_le32(0);
desc_virtual->num_pages = cpu_to_le32(0);
- kunmap_atomic(page_virtual);
}
- desc_dma = 0;
- list_for_each_entry_reverse(page, desc_pages, lru) {
- page_virtual = kmap_atomic(page);
- page_virtual[desc_per_page].ppn = cpu_to_le32
- (desc_dma >> PAGE_SHIFT);
+ if (likely(page_virtual != NULL))
kunmap_atomic(page_virtual);
- desc_dma = dma_map_page(dev, page, 0, PAGE_SIZE,
- DMA_TO_DEVICE);
-
- if (unlikely(dma_mapping_error(dev, desc_dma)))
- goto out_err;
- }
- *first_dma = desc_dma;
return 0;
out_err:
- vmw_gmr_free_descriptors(dev, DMA_ADDR_INVALID, desc_pages);
+ list_for_each_entry_safe(page, next, desc_pages, lru) {
+ list_del_init(&page->lru);
+ __free_page(page);
+ }
return ret;
}
+static inline void vmw_gmr_free_descriptors(struct list_head *desc_pages)
+{
+ struct page *page, *next;
+
+ list_for_each_entry_safe(page, next, desc_pages, lru) {
+ list_del_init(&page->lru);
+ __free_page(page);
+ }
+}
+
static void vmw_gmr_fire_descriptors(struct vmw_private *dev_priv,
- int gmr_id, dma_addr_t desc_dma)
+ int gmr_id, struct list_head *desc_pages)
{
+ struct page *page;
+
+ if (unlikely(list_empty(desc_pages)))
+ return;
+
+ page = list_entry(desc_pages->next, struct page, lru);
+
mutex_lock(&dev_priv->hw_mutex);
vmw_write(dev_priv, SVGA_REG_GMR_ID, gmr_id);
wmb();
- vmw_write(dev_priv, SVGA_REG_GMR_DESCRIPTOR, desc_dma >> PAGE_SHIFT);
+ vmw_write(dev_priv, SVGA_REG_GMR_DESCRIPTOR, page_to_pfn(page));
mb();
mutex_unlock(&dev_priv->hw_mutex);
}
+/**
+ * FIXME: Adjust to the ttm lowmem / highmem storage to minimize
+ * the number of used descriptors.
+ */
+
+static unsigned long vmw_gmr_count_descriptors(struct page *pages[],
+ unsigned long num_pages)
+{
+ unsigned long prev_pfn = ~(0UL);
+ unsigned long pfn;
+ unsigned long descriptors = 0;
+
+ while (num_pages--) {
+ pfn = page_to_pfn(*pages++);
+ if (prev_pfn + 1 != pfn)
+ ++descriptors;
+ prev_pfn = pfn;
+ }
+
+ return descriptors;
+}
+
int vmw_gmr_bind(struct vmw_private *dev_priv,
- const struct vmw_sg_table *vsgt,
+ struct page *pages[],
unsigned long num_pages,
int gmr_id)
{
struct list_head desc_pages;
- dma_addr_t desc_dma = 0;
- struct device *dev = dev_priv->dev->dev;
- struct vmw_piter data_iter;
int ret;
- vmw_piter_start(&data_iter, vsgt, 0);
-
- if (unlikely(!vmw_piter_next(&data_iter)))
- return 0;
-
if (likely(dev_priv->capabilities & SVGA_CAP_GMR2))
- return vmw_gmr2_bind(dev_priv, &data_iter, num_pages, gmr_id);
+ return vmw_gmr2_bind(dev_priv, pages, num_pages, gmr_id);
if (unlikely(!(dev_priv->capabilities & SVGA_CAP_GMR)))
return -EINVAL;
- if (vsgt->num_regions > dev_priv->max_gmr_descriptors)
+ if (vmw_gmr_count_descriptors(pages, num_pages) >
+ dev_priv->max_gmr_descriptors)
return -EINVAL;
INIT_LIST_HEAD(&desc_pages);
- ret = vmw_gmr_build_descriptors(dev, &desc_pages, &data_iter,
- num_pages, &desc_dma);
+ ret = vmw_gmr_build_descriptors(&desc_pages, pages, num_pages);
if (unlikely(ret != 0))
return ret;
- vmw_gmr_fire_descriptors(dev_priv, gmr_id, desc_dma);
- vmw_gmr_free_descriptors(dev, desc_dma, &desc_pages);
+ vmw_gmr_fire_descriptors(dev_priv, gmr_id, &desc_pages);
+ vmw_gmr_free_descriptors(&desc_pages);
return 0;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index a51f48e..c509d40 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -168,7 +168,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
fb = drm_framebuffer_lookup(dev, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
- ret = -ENOENT;
+ ret = -EINVAL;
goto out_no_fb;
}
vfb = vmw_framebuffer_to_vfb(fb);
@@ -252,7 +252,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
fb = drm_framebuffer_lookup(dev, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
- ret = -ENOENT;
+ ret = -EINVAL;
goto out_no_fb;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 03f1c20..fc43c06 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -75,7 +75,6 @@ void vmw_display_unit_cleanup(struct vmw_display_unit *du)
vmw_surface_unreference(&du->cursor_surface);
if (du->cursor_dmabuf)
vmw_dmabuf_unreference(&du->cursor_dmabuf);
- drm_sysfs_connector_remove(&du->connector);
drm_crtc_cleanup(&du->crtc);
drm_encoder_cleanup(&du->encoder);
drm_connector_cleanup(&du->connector);
@@ -1509,7 +1508,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, arg->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
- ret = -ENOENT;
+ ret = -EINVAL;
goto out;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index a055a26..79f7e8e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -260,7 +260,6 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
connector->encoder = NULL;
encoder->crtc = NULL;
crtc->fb = NULL;
- crtc->enabled = false;
vmw_ldu_del_active(dev_priv, ldu);
@@ -286,7 +285,6 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
crtc->x = set->x;
crtc->y = set->y;
crtc->mode = *mode;
- crtc->enabled = true;
vmw_ldu_add_active(dev_priv, ldu, vfb);
@@ -371,8 +369,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
encoder->possible_crtcs = (1 << unit);
encoder->possible_clones = 0;
- (void) drm_sysfs_connector_add(connector);
-
drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs);
drm_mode_crtc_set_gamma_size(crtc, 256);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c b/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
deleted file mode 100644
index 31fe32d..0000000
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/**************************************************************************
- *
- * Copyright © 2013 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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:
- * Thomas Hellstrom <thellstrom@vmware.com>
- *
- */
-
-#include "vmwgfx_drv.h"
-#include <linux/dma-buf.h>
-#include <drm/ttm/ttm_object.h>
-
-/*
- * DMA-BUF attach- and mapping methods. No need to implement
- * these until we have other virtual devices use them.
- */
-
-static int vmw_prime_map_attach(struct dma_buf *dma_buf,
- struct device *target_dev,
- struct dma_buf_attachment *attach)
-{
- return -ENOSYS;
-}
-
-static void vmw_prime_map_detach(struct dma_buf *dma_buf,
- struct dma_buf_attachment *attach)
-{
-}
-
-static struct sg_table *vmw_prime_map_dma_buf(struct dma_buf_attachment *attach,
- enum dma_data_direction dir)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static void vmw_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
- struct sg_table *sgb,
- enum dma_data_direction dir)
-{
-}
-
-static void *vmw_prime_dmabuf_vmap(struct dma_buf *dma_buf)
-{
- return NULL;
-}
-
-static void vmw_prime_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
-{
-}
-
-static void *vmw_prime_dmabuf_kmap_atomic(struct dma_buf *dma_buf,
- unsigned long page_num)
-{
- return NULL;
-}
-
-static void vmw_prime_dmabuf_kunmap_atomic(struct dma_buf *dma_buf,
- unsigned long page_num, void *addr)
-{
-
-}
-static void *vmw_prime_dmabuf_kmap(struct dma_buf *dma_buf,
- unsigned long page_num)
-{
- return NULL;
-}
-
-static void vmw_prime_dmabuf_kunmap(struct dma_buf *dma_buf,
- unsigned long page_num, void *addr)
-{
-
-}
-
-static int vmw_prime_dmabuf_mmap(struct dma_buf *dma_buf,
- struct vm_area_struct *vma)
-{
- WARN_ONCE(true, "Attempted use of dmabuf mmap. Bad.\n");
- return -ENOSYS;
-}
-
-const struct dma_buf_ops vmw_prime_dmabuf_ops = {
- .attach = vmw_prime_map_attach,
- .detach = vmw_prime_map_detach,
- .map_dma_buf = vmw_prime_map_dma_buf,
- .unmap_dma_buf = vmw_prime_unmap_dma_buf,
- .release = NULL,
- .kmap = vmw_prime_dmabuf_kmap,
- .kmap_atomic = vmw_prime_dmabuf_kmap_atomic,
- .kunmap = vmw_prime_dmabuf_kunmap,
- .kunmap_atomic = vmw_prime_dmabuf_kunmap_atomic,
- .mmap = vmw_prime_dmabuf_mmap,
- .vmap = vmw_prime_dmabuf_vmap,
- .vunmap = vmw_prime_dmabuf_vunmap,
-};
-
-int vmw_prime_fd_to_handle(struct drm_device *dev,
- struct drm_file *file_priv,
- int fd, u32 *handle)
-{
- struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
-
- return ttm_prime_fd_to_handle(tfile, fd, handle);
-}
-
-int vmw_prime_handle_to_fd(struct drm_device *dev,
- struct drm_file *file_priv,
- uint32_t handle, uint32_t flags,
- int *prime_fd)
-{
- struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
-
- return ttm_prime_handle_to_fd(tfile, handle, flags, prime_fd);
-}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 9b5ea2a..37fb4be 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -32,10 +32,8 @@
#include <drm/drmP.h>
#include "vmwgfx_resource_priv.h"
-#define VMW_RES_EVICT_ERR_COUNT 10
-
struct vmw_user_dma_buffer {
- struct ttm_prime_object prime;
+ struct ttm_base_object base;
struct vmw_dma_buffer dma;
};
@@ -297,7 +295,7 @@ int vmw_user_resource_lookup_handle(struct vmw_private *dev_priv,
if (unlikely(base == NULL))
return -EINVAL;
- if (unlikely(ttm_base_object_type(base) != converter->object_type))
+ if (unlikely(base->object_type != converter->object_type))
goto out_bad_resource;
res = converter->base_obj_to_res(base);
@@ -352,38 +350,6 @@ int vmw_user_lookup_handle(struct vmw_private *dev_priv,
/**
* Buffer management.
*/
-
-/**
- * vmw_dmabuf_acc_size - Calculate the pinned memory usage of buffers
- *
- * @dev_priv: Pointer to a struct vmw_private identifying the device.
- * @size: The requested buffer size.
- * @user: Whether this is an ordinary dma buffer or a user dma buffer.
- */
-static size_t vmw_dmabuf_acc_size(struct vmw_private *dev_priv, size_t size,
- bool user)
-{
- static size_t struct_size, user_struct_size;
- size_t num_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
- size_t page_array_size = ttm_round_pot(num_pages * sizeof(void *));
-
- if (unlikely(struct_size == 0)) {
- size_t backend_size = ttm_round_pot(vmw_tt_size);
-
- struct_size = backend_size +
- ttm_round_pot(sizeof(struct vmw_dma_buffer));
- user_struct_size = backend_size +
- ttm_round_pot(sizeof(struct vmw_user_dma_buffer));
- }
-
- if (dev_priv->map_mode == vmw_dma_alloc_coherent)
- page_array_size +=
- ttm_round_pot(num_pages * sizeof(dma_addr_t));
-
- return ((user) ? user_struct_size : struct_size) +
- page_array_size;
-}
-
void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo)
{
struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
@@ -391,13 +357,6 @@ void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo)
kfree(vmw_bo);
}
-static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo)
-{
- struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo);
-
- ttm_prime_object_kfree(vmw_user_bo, prime);
-}
-
int vmw_dmabuf_init(struct vmw_private *dev_priv,
struct vmw_dma_buffer *vmw_bo,
size_t size, struct ttm_placement *placement,
@@ -407,23 +366,28 @@ int vmw_dmabuf_init(struct vmw_private *dev_priv,
struct ttm_bo_device *bdev = &dev_priv->bdev;
size_t acc_size;
int ret;
- bool user = (bo_free == &vmw_user_dmabuf_destroy);
- BUG_ON(!bo_free && (!user && (bo_free != vmw_dmabuf_bo_free)));
+ BUG_ON(!bo_free);
- acc_size = vmw_dmabuf_acc_size(dev_priv, size, user);
+ acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct vmw_dma_buffer));
memset(vmw_bo, 0, sizeof(*vmw_bo));
INIT_LIST_HEAD(&vmw_bo->res_list);
ret = ttm_bo_init(bdev, &vmw_bo->base, size,
- (user) ? ttm_bo_type_device :
- ttm_bo_type_kernel, placement,
+ ttm_bo_type_device, placement,
0, interruptible,
NULL, acc_size, NULL, bo_free);
return ret;
}
+static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo)
+{
+ struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo);
+
+ ttm_base_object_kfree(vmw_user_bo, base);
+}
+
static void vmw_user_dmabuf_release(struct ttm_base_object **p_base)
{
struct vmw_user_dma_buffer *vmw_user_bo;
@@ -435,8 +399,7 @@ static void vmw_user_dmabuf_release(struct ttm_base_object **p_base)
if (unlikely(base == NULL))
return;
- vmw_user_bo = container_of(base, struct vmw_user_dma_buffer,
- prime.base);
+ vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base);
bo = &vmw_user_bo->dma.base;
ttm_bo_unref(&bo);
}
@@ -477,19 +440,18 @@ int vmw_user_dmabuf_alloc(struct vmw_private *dev_priv,
return ret;
tmp = ttm_bo_reference(&user_bo->dma.base);
- ret = ttm_prime_object_init(tfile,
- size,
- &user_bo->prime,
- shareable,
- ttm_buffer_type,
- &vmw_user_dmabuf_release, NULL);
+ ret = ttm_base_object_init(tfile,
+ &user_bo->base,
+ shareable,
+ ttm_buffer_type,
+ &vmw_user_dmabuf_release, NULL);
if (unlikely(ret != 0)) {
ttm_bo_unref(&tmp);
goto out_no_base_object;
}
*p_dma_buf = &user_bo->dma;
- *handle = user_bo->prime.base.hash.key;
+ *handle = user_bo->base.hash.key;
out_no_base_object:
return ret;
@@ -511,8 +473,8 @@ int vmw_user_dmabuf_verify_access(struct ttm_buffer_object *bo,
return -EPERM;
vmw_user_bo = vmw_user_dma_buffer(bo);
- return (vmw_user_bo->prime.base.tfile == tfile ||
- vmw_user_bo->prime.base.shareable) ? 0 : -EPERM;
+ return (vmw_user_bo->base.tfile == tfile ||
+ vmw_user_bo->base.shareable) ? 0 : -EPERM;
}
int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
@@ -574,15 +536,14 @@ int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile,
return -ESRCH;
}
- if (unlikely(ttm_base_object_type(base) != ttm_buffer_type)) {
+ if (unlikely(base->object_type != ttm_buffer_type)) {
ttm_base_object_unref(&base);
printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
(unsigned long)handle);
return -EINVAL;
}
- vmw_user_bo = container_of(base, struct vmw_user_dma_buffer,
- prime.base);
+ vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base);
(void)ttm_bo_reference(&vmw_user_bo->dma.base);
ttm_base_object_unref(&base);
*out = &vmw_user_bo->dma;
@@ -599,8 +560,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile,
return -EINVAL;
user_bo = container_of(dma_buf, struct vmw_user_dma_buffer, dma);
- return ttm_ref_object_add(tfile, &user_bo->prime.base,
- TTM_REF_USAGE, NULL);
+ return ttm_ref_object_add(tfile, &user_bo->base, TTM_REF_USAGE, NULL);
}
/*
@@ -815,55 +775,53 @@ err_ref:
}
-/**
- * vmw_dumb_create - Create a dumb kms buffer
- *
- * @file_priv: Pointer to a struct drm_file identifying the caller.
- * @dev: Pointer to the drm device.
- * @args: Pointer to a struct drm_mode_create_dumb structure
- *
- * This is a driver callback for the core drm create_dumb functionality.
- * Note that this is very similar to the vmw_dmabuf_alloc ioctl, except
- * that the arguments have a different format.
- */
int vmw_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args)
{
struct vmw_private *dev_priv = vmw_priv(dev);
struct vmw_master *vmaster = vmw_master(file_priv->master);
- struct vmw_dma_buffer *dma_buf;
+ struct vmw_user_dma_buffer *vmw_user_bo;
+ struct ttm_buffer_object *tmp;
int ret;
args->pitch = args->width * ((args->bpp + 7) / 8);
args->size = args->pitch * args->height;
+ vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL);
+ if (vmw_user_bo == NULL)
+ return -ENOMEM;
+
ret = ttm_read_lock(&vmaster->lock, true);
- if (unlikely(ret != 0))
+ if (ret != 0) {
+ kfree(vmw_user_bo);
return ret;
+ }
- ret = vmw_user_dmabuf_alloc(dev_priv, vmw_fpriv(file_priv)->tfile,
- args->size, false, &args->handle,
- &dma_buf);
- if (unlikely(ret != 0))
+ ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size,
+ &vmw_vram_sys_placement, true,
+ &vmw_user_dmabuf_destroy);
+ if (ret != 0)
goto out_no_dmabuf;
- vmw_dmabuf_unreference(&dma_buf);
+ tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
+ ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
+ &vmw_user_bo->base,
+ false,
+ ttm_buffer_type,
+ &vmw_user_dmabuf_release, NULL);
+ if (unlikely(ret != 0))
+ goto out_no_base_object;
+
+ args->handle = vmw_user_bo->base.hash.key;
+
+out_no_base_object:
+ ttm_bo_unref(&tmp);
out_no_dmabuf:
ttm_read_unlock(&vmaster->lock);
return ret;
}
-/**
- * vmw_dumb_map_offset - Return the address space offset of a dumb buffer
- *
- * @file_priv: Pointer to a struct drm_file identifying the caller.
- * @dev: Pointer to the drm device.
- * @handle: Handle identifying the dumb buffer.
- * @offset: The address space offset returned.
- *
- * This is a driver callback for the core drm dumb_map_offset functionality.
- */
int vmw_dumb_map_offset(struct drm_file *file_priv,
struct drm_device *dev, uint32_t handle,
uint64_t *offset)
@@ -881,15 +839,6 @@ int vmw_dumb_map_offset(struct drm_file *file_priv,
return 0;
}
-/**
- * vmw_dumb_destroy - Destroy a dumb boffer
- *
- * @file_priv: Pointer to a struct drm_file identifying the caller.
- * @dev: Pointer to the drm device.
- * @handle: Handle identifying the dumb buffer.
- *
- * This is a driver callback for the core drm dumb_destroy functionality.
- */
int vmw_dumb_destroy(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle)
@@ -1043,6 +992,7 @@ void vmw_resource_unreserve(struct vmw_resource *res,
*/
static int
vmw_resource_check_buffer(struct vmw_resource *res,
+ struct ww_acquire_ctx *ticket,
bool interruptible,
struct ttm_validate_buffer *val_buf)
{
@@ -1059,7 +1009,7 @@ vmw_resource_check_buffer(struct vmw_resource *res,
INIT_LIST_HEAD(&val_list);
val_buf->bo = ttm_bo_reference(&res->backup->base);
list_add_tail(&val_buf->head, &val_list);
- ret = ttm_eu_reserve_buffers(NULL, &val_list);
+ ret = ttm_eu_reserve_buffers(ticket, &val_list);
if (unlikely(ret != 0))
goto out_no_reserve;
@@ -1077,7 +1027,7 @@ vmw_resource_check_buffer(struct vmw_resource *res,
return 0;
out_no_validate:
- ttm_eu_backoff_reservation(NULL, &val_list);
+ ttm_eu_backoff_reservation(ticket, &val_list);
out_no_reserve:
ttm_bo_unref(&val_buf->bo);
if (backup_dirty)
@@ -1122,7 +1072,8 @@ int vmw_resource_reserve(struct vmw_resource *res, bool no_backup)
* @val_buf: Backup buffer information.
*/
static void
-vmw_resource_backoff_reservation(struct ttm_validate_buffer *val_buf)
+vmw_resource_backoff_reservation(struct ww_acquire_ctx *ticket,
+ struct ttm_validate_buffer *val_buf)
{
struct list_head val_list;
@@ -1131,7 +1082,7 @@ vmw_resource_backoff_reservation(struct ttm_validate_buffer *val_buf)
INIT_LIST_HEAD(&val_list);
list_add_tail(&val_buf->head, &val_list);
- ttm_eu_backoff_reservation(NULL, &val_list);
+ ttm_eu_backoff_reservation(ticket, &val_list);
ttm_bo_unref(&val_buf->bo);
}
@@ -1140,18 +1091,18 @@ vmw_resource_backoff_reservation(struct ttm_validate_buffer *val_buf)
* to a backup buffer.
*
* @res: The resource to evict.
- * @interruptible: Whether to wait interruptible.
*/
-int vmw_resource_do_evict(struct vmw_resource *res, bool interruptible)
+int vmw_resource_do_evict(struct vmw_resource *res)
{
struct ttm_validate_buffer val_buf;
const struct vmw_res_func *func = res->func;
+ struct ww_acquire_ctx ticket;
int ret;
BUG_ON(!func->may_evict);
val_buf.bo = NULL;
- ret = vmw_resource_check_buffer(res, interruptible, &val_buf);
+ ret = vmw_resource_check_buffer(res, &ticket, true, &val_buf);
if (unlikely(ret != 0))
return ret;
@@ -1166,7 +1117,7 @@ int vmw_resource_do_evict(struct vmw_resource *res, bool interruptible)
res->backup_dirty = true;
res->res_dirty = false;
out_no_unbind:
- vmw_resource_backoff_reservation(&val_buf);
+ vmw_resource_backoff_reservation(&ticket, &val_buf);
return ret;
}
@@ -1190,7 +1141,6 @@ int vmw_resource_validate(struct vmw_resource *res)
struct vmw_private *dev_priv = res->dev_priv;
struct list_head *lru_list = &dev_priv->res_lru[res->func->res_type];
struct ttm_validate_buffer val_buf;
- unsigned err_count = 0;
if (likely(!res->func->may_evict))
return 0;
@@ -1205,7 +1155,7 @@ int vmw_resource_validate(struct vmw_resource *res)
write_lock(&dev_priv->resource_lock);
if (list_empty(lru_list) || !res->func->may_evict) {
- DRM_ERROR("Out of device device resources "
+ DRM_ERROR("Out of device device id entries "
"for %s.\n", res->func->type_name);
ret = -EBUSY;
write_unlock(&dev_priv->resource_lock);
@@ -1218,19 +1168,7 @@ int vmw_resource_validate(struct vmw_resource *res)
list_del_init(&evict_res->lru_head);
write_unlock(&dev_priv->resource_lock);
-
- ret = vmw_resource_do_evict(evict_res, true);
- if (unlikely(ret != 0)) {
- write_lock(&dev_priv->resource_lock);
- list_add_tail(&evict_res->lru_head, lru_list);
- write_unlock(&dev_priv->resource_lock);
- if (ret == -ERESTARTSYS ||
- ++err_count > VMW_RES_EVICT_ERR_COUNT) {
- vmw_resource_unreference(&evict_res);
- goto out_no_validate;
- }
- }
-
+ vmw_resource_do_evict(evict_res);
vmw_resource_unreference(&evict_res);
} while (1);
@@ -1315,15 +1253,13 @@ bool vmw_resource_needs_backup(const struct vmw_resource *res)
* @type: The resource type to evict
*
* To avoid thrashing starvation or as part of the hibernation sequence,
- * try to evict all evictable resources of a specific type.
+ * evict all evictable resources of a specific type.
*/
static void vmw_resource_evict_type(struct vmw_private *dev_priv,
enum vmw_res_type type)
{
struct list_head *lru_list = &dev_priv->res_lru[type];
struct vmw_resource *evict_res;
- unsigned err_count = 0;
- int ret;
do {
write_lock(&dev_priv->resource_lock);
@@ -1336,18 +1272,7 @@ static void vmw_resource_evict_type(struct vmw_private *dev_priv,
lru_head));
list_del_init(&evict_res->lru_head);
write_unlock(&dev_priv->resource_lock);
-
- ret = vmw_resource_do_evict(evict_res, false);
- if (unlikely(ret != 0)) {
- write_lock(&dev_priv->resource_lock);
- list_add_tail(&evict_res->lru_head, lru_list);
- write_unlock(&dev_priv->resource_lock);
- if (++err_count > VMW_RES_EVICT_ERR_COUNT) {
- vmw_resource_unreference(&evict_res);
- return;
- }
- }
-
+ vmw_resource_do_evict(evict_res);
vmw_resource_unreference(&evict_res);
} while (1);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 22406c8..26387c3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -310,7 +310,6 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
crtc->fb = NULL;
crtc->x = 0;
crtc->y = 0;
- crtc->enabled = false;
vmw_sou_del_active(dev_priv, sou);
@@ -371,7 +370,6 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
crtc->fb = NULL;
crtc->x = 0;
crtc->y = 0;
- crtc->enabled = false;
return ret;
}
@@ -384,7 +382,6 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
crtc->fb = fb;
crtc->x = set->x;
crtc->y = set->y;
- crtc->enabled = true;
return 0;
}
@@ -467,8 +464,6 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
encoder->possible_crtcs = (1 << unit);
encoder->possible_clones = 0;
- (void) drm_sysfs_connector_add(connector);
-
drm_crtc_init(dev, crtc, &vmw_screen_object_crtc_funcs);
drm_mode_crtc_set_gamma_size(crtc, 256);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 7de2ea8..5828143 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -38,7 +38,7 @@
* @size: TTM accounting size for the surface.
*/
struct vmw_user_surface {
- struct ttm_prime_object prime;
+ struct ttm_base_object base;
struct vmw_surface srf;
uint32_t size;
uint32_t backup_handle;
@@ -580,8 +580,7 @@ static int vmw_surface_init(struct vmw_private *dev_priv,
static struct vmw_resource *
vmw_user_surface_base_to_res(struct ttm_base_object *base)
{
- return &(container_of(base, struct vmw_user_surface,
- prime.base)->srf.res);
+ return &(container_of(base, struct vmw_user_surface, base)->srf.res);
}
/**
@@ -600,7 +599,7 @@ static void vmw_user_surface_free(struct vmw_resource *res)
kfree(srf->offsets);
kfree(srf->sizes);
kfree(srf->snooper.image);
- ttm_prime_object_kfree(user_srf, prime);
+ ttm_base_object_kfree(user_srf, base);
ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
}
@@ -617,7 +616,7 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
{
struct ttm_base_object *base = *p_base;
struct vmw_user_surface *user_srf =
- container_of(base, struct vmw_user_surface, prime.base);
+ container_of(base, struct vmw_user_surface, base);
struct vmw_resource *res = &user_srf->srf.res;
*p_base = NULL;
@@ -791,8 +790,8 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
}
srf->snooper.crtc = NULL;
- user_srf->prime.base.shareable = false;
- user_srf->prime.base.tfile = NULL;
+ user_srf->base.shareable = false;
+ user_srf->base.tfile = NULL;
/**
* From this point, the generic resource management functions
@@ -804,9 +803,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
goto out_unlock;
tmp = vmw_resource_reference(&srf->res);
- ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
- req->shareable, VMW_RES_SURFACE,
- &vmw_user_surface_base_release, NULL);
+ ret = ttm_base_object_init(tfile, &user_srf->base,
+ req->shareable, VMW_RES_SURFACE,
+ &vmw_user_surface_base_release, NULL);
if (unlikely(ret != 0)) {
vmw_resource_unreference(&tmp);
@@ -814,7 +813,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
goto out_unlock;
}
- rep->sid = user_srf->prime.base.hash.key;
+ rep->sid = user_srf->base.hash.key;
vmw_resource_unreference(&res);
ttm_read_unlock(&vmaster->lock);
@@ -824,7 +823,7 @@ out_no_copy:
out_no_offsets:
kfree(srf->sizes);
out_no_sizes:
- ttm_prime_object_kfree(user_srf, prime);
+ ttm_base_object_kfree(user_srf, base);
out_no_user_srf:
ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
out_unlock:
@@ -860,14 +859,13 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
- if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE))
+ if (unlikely(base->object_type != VMW_RES_SURFACE))
goto out_bad_resource;
- user_srf = container_of(base, struct vmw_user_surface, prime.base);
+ user_srf = container_of(base, struct vmw_user_surface, base);
srf = &user_srf->srf;
- ret = ttm_ref_object_add(tfile, &user_srf->prime.base,
- TTM_REF_USAGE, NULL);
+ ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL);
if (unlikely(ret != 0)) {
DRM_ERROR("Could not add a reference to a surface.\n");
goto out_no_reference;
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 7d6bed2..ccfd42b 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -19,4 +19,6 @@ config TEGRA_HOST1X_FIREWALL
If unsure, choose Y.
+source "drivers/gpu/host1x/drm/Kconfig"
+
endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index afa1e9e..3b037b6 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -1,5 +1,6 @@
+ccflags-y = -Idrivers/gpu/host1x
+
host1x-y = \
- bus.o \
syncpt.o \
dev.o \
intr.o \
@@ -7,7 +8,13 @@ host1x-y = \
channel.o \
job.o \
debug.o \
- hw/host1x01.o \
- hw/host1x02.o
+ hw/host1x01.o
+
+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
deleted file mode 100644
index 6a92959..0000000
--- a/drivers/gpu/host1x/bus.c
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012-2013, NVIDIA Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/host1x.h>
-#include <linux/of.h>
-#include <linux/slab.h>
-
-#include "bus.h"
-#include "dev.h"
-
-static DEFINE_MUTEX(clients_lock);
-static LIST_HEAD(clients);
-
-static DEFINE_MUTEX(drivers_lock);
-static LIST_HEAD(drivers);
-
-static DEFINE_MUTEX(devices_lock);
-static LIST_HEAD(devices);
-
-struct host1x_subdev {
- struct host1x_client *client;
- struct device_node *np;
- struct list_head list;
-};
-
-/**
- * host1x_subdev_add() - add a new subdevice with an associated device node
- */
-static int host1x_subdev_add(struct host1x_device *device,
- struct device_node *np)
-{
- struct host1x_subdev *subdev;
-
- subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
- if (!subdev)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&subdev->list);
- subdev->np = of_node_get(np);
-
- mutex_lock(&device->subdevs_lock);
- list_add_tail(&subdev->list, &device->subdevs);
- mutex_unlock(&device->subdevs_lock);
-
- return 0;
-}
-
-/**
- * host1x_subdev_del() - remove subdevice
- */
-static void host1x_subdev_del(struct host1x_subdev *subdev)
-{
- list_del(&subdev->list);
- of_node_put(subdev->np);
- kfree(subdev);
-}
-
-/**
- * host1x_device_parse_dt() - scan device tree and add matching subdevices
- */
-static int host1x_device_parse_dt(struct host1x_device *device)
-{
- struct device_node *np;
- int err;
-
- for_each_child_of_node(device->dev.parent->of_node, np) {
- if (of_match_node(device->driver->subdevs, np) &&
- of_device_is_available(np)) {
- err = host1x_subdev_add(device, np);
- if (err < 0)
- return err;
- }
- }
-
- return 0;
-}
-
-static void host1x_subdev_register(struct host1x_device *device,
- struct host1x_subdev *subdev,
- struct host1x_client *client)
-{
- int err;
-
- /*
- * Move the subdevice to the list of active (registered) subdevices
- * and associate it with a client. At the same time, associate the
- * client with its parent device.
- */
- mutex_lock(&device->subdevs_lock);
- mutex_lock(&device->clients_lock);
- list_move_tail(&client->list, &device->clients);
- list_move_tail(&subdev->list, &device->active);
- client->parent = &device->dev;
- subdev->client = client;
- mutex_unlock(&device->clients_lock);
- mutex_unlock(&device->subdevs_lock);
-
- /*
- * When all subdevices have been registered, the composite device is
- * ready to be probed.
- */
- if (list_empty(&device->subdevs)) {
- err = device->driver->probe(device);
- if (err < 0)
- dev_err(&device->dev, "probe failed: %d\n", err);
- }
-}
-
-static void __host1x_subdev_unregister(struct host1x_device *device,
- struct host1x_subdev *subdev)
-{
- struct host1x_client *client = subdev->client;
- int err;
-
- /*
- * If all subdevices have been activated, we're about to remove the
- * first active subdevice, so unload the driver first.
- */
- if (list_empty(&device->subdevs)) {
- err = device->driver->remove(device);
- if (err < 0)
- dev_err(&device->dev, "remove failed: %d\n", err);
- }
-
- /*
- * Move the subdevice back to the list of idle subdevices and remove
- * it from list of clients.
- */
- mutex_lock(&device->clients_lock);
- subdev->client = NULL;
- client->parent = NULL;
- list_move_tail(&subdev->list, &device->subdevs);
- /*
- * XXX: Perhaps don't do this here, but rather explicitly remove it
- * when the device is about to be deleted.
- *
- * This is somewhat complicated by the fact that this function is
- * used to remove the subdevice when a client is unregistered but
- * also when the composite device is about to be removed.
- */
- list_del_init(&client->list);
- mutex_unlock(&device->clients_lock);
-}
-
-static void host1x_subdev_unregister(struct host1x_device *device,
- struct host1x_subdev *subdev)
-{
- mutex_lock(&device->subdevs_lock);
- __host1x_subdev_unregister(device, subdev);
- mutex_unlock(&device->subdevs_lock);
-}
-
-int host1x_device_init(struct host1x_device *device)
-{
- struct host1x_client *client;
- int err;
-
- mutex_lock(&device->clients_lock);
-
- list_for_each_entry(client, &device->clients, list) {
- if (client->ops && client->ops->init) {
- err = client->ops->init(client);
- if (err < 0) {
- dev_err(&device->dev,
- "failed to initialize %s: %d\n",
- dev_name(client->dev), err);
- mutex_unlock(&device->clients_lock);
- return err;
- }
- }
- }
-
- mutex_unlock(&device->clients_lock);
-
- return 0;
-}
-
-int host1x_device_exit(struct host1x_device *device)
-{
- struct host1x_client *client;
- int err;
-
- mutex_lock(&device->clients_lock);
-
- list_for_each_entry_reverse(client, &device->clients, list) {
- if (client->ops && client->ops->exit) {
- err = client->ops->exit(client);
- if (err < 0) {
- dev_err(&device->dev,
- "failed to cleanup %s: %d\n",
- dev_name(client->dev), err);
- mutex_unlock(&device->clients_lock);
- return err;
- }
- }
- }
-
- mutex_unlock(&device->clients_lock);
-
- return 0;
-}
-
-static int host1x_register_client(struct host1x *host1x,
- struct host1x_client *client)
-{
- struct host1x_device *device;
- struct host1x_subdev *subdev;
-
- mutex_lock(&host1x->devices_lock);
-
- list_for_each_entry(device, &host1x->devices, list) {
- list_for_each_entry(subdev, &device->subdevs, list) {
- if (subdev->np == client->dev->of_node) {
- host1x_subdev_register(device, subdev, client);
- mutex_unlock(&host1x->devices_lock);
- return 0;
- }
- }
- }
-
- mutex_unlock(&host1x->devices_lock);
- return -ENODEV;
-}
-
-static int host1x_unregister_client(struct host1x *host1x,
- struct host1x_client *client)
-{
- struct host1x_device *device, *dt;
- struct host1x_subdev *subdev;
-
- mutex_lock(&host1x->devices_lock);
-
- list_for_each_entry_safe(device, dt, &host1x->devices, list) {
- list_for_each_entry(subdev, &device->active, list) {
- if (subdev->client == client) {
- host1x_subdev_unregister(device, subdev);
- mutex_unlock(&host1x->devices_lock);
- return 0;
- }
- }
- }
-
- mutex_unlock(&host1x->devices_lock);
- return -ENODEV;
-}
-
-static struct bus_type host1x_bus_type = {
- .name = "host1x",
-};
-
-int host1x_bus_init(void)
-{
- return bus_register(&host1x_bus_type);
-}
-
-void host1x_bus_exit(void)
-{
- bus_unregister(&host1x_bus_type);
-}
-
-static void host1x_device_release(struct device *dev)
-{
- struct host1x_device *device = to_host1x_device(dev);
-
- kfree(device);
-}
-
-static int host1x_device_add(struct host1x *host1x,
- struct host1x_driver *driver)
-{
- struct host1x_client *client, *tmp;
- struct host1x_subdev *subdev;
- struct host1x_device *device;
- int err;
-
- device = kzalloc(sizeof(*device), GFP_KERNEL);
- if (!device)
- return -ENOMEM;
-
- mutex_init(&device->subdevs_lock);
- INIT_LIST_HEAD(&device->subdevs);
- INIT_LIST_HEAD(&device->active);
- mutex_init(&device->clients_lock);
- INIT_LIST_HEAD(&device->clients);
- INIT_LIST_HEAD(&device->list);
- device->driver = driver;
-
- device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
- device->dev.dma_mask = &device->dev.coherent_dma_mask;
- device->dev.release = host1x_device_release;
- dev_set_name(&device->dev, "%s", driver->name);
- device->dev.bus = &host1x_bus_type;
- device->dev.parent = host1x->dev;
-
- err = device_register(&device->dev);
- if (err < 0)
- return err;
-
- err = host1x_device_parse_dt(device);
- if (err < 0) {
- device_unregister(&device->dev);
- return err;
- }
-
- mutex_lock(&host1x->devices_lock);
- list_add_tail(&device->list, &host1x->devices);
- mutex_unlock(&host1x->devices_lock);
-
- mutex_lock(&clients_lock);
-
- list_for_each_entry_safe(client, tmp, &clients, list) {
- list_for_each_entry(subdev, &device->subdevs, list) {
- if (subdev->np == client->dev->of_node) {
- host1x_subdev_register(device, subdev, client);
- break;
- }
- }
- }
-
- mutex_unlock(&clients_lock);
-
- return 0;
-}
-
-/*
- * Removes a device by first unregistering any subdevices and then removing
- * itself from the list of devices.
- *
- * This function must be called with the host1x->devices_lock held.
- */
-static void host1x_device_del(struct host1x *host1x,
- struct host1x_device *device)
-{
- struct host1x_subdev *subdev, *sd;
- struct host1x_client *client, *cl;
-
- mutex_lock(&device->subdevs_lock);
-
- /* unregister subdevices */
- list_for_each_entry_safe(subdev, sd, &device->active, list) {
- /*
- * host1x_subdev_unregister() will remove the client from
- * any lists, so we'll need to manually add it back to the
- * list of idle clients.
- *
- * XXX: Alternatively, perhaps don't remove the client from
- * any lists in host1x_subdev_unregister() and instead do
- * that explicitly from host1x_unregister_client()?
- */
- client = subdev->client;
-
- __host1x_subdev_unregister(device, subdev);
-
- /* add the client to the list of idle clients */
- mutex_lock(&clients_lock);
- list_add_tail(&client->list, &clients);
- mutex_unlock(&clients_lock);
- }
-
- /* remove subdevices */
- list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
- host1x_subdev_del(subdev);
-
- mutex_unlock(&device->subdevs_lock);
-
- /* move clients to idle list */
- mutex_lock(&clients_lock);
- mutex_lock(&device->clients_lock);
-
- list_for_each_entry_safe(client, cl, &device->clients, list)
- list_move_tail(&client->list, &clients);
-
- mutex_unlock(&device->clients_lock);
- mutex_unlock(&clients_lock);
-
- /* finally remove the device */
- list_del_init(&device->list);
- device_unregister(&device->dev);
-}
-
-static void host1x_attach_driver(struct host1x *host1x,
- struct host1x_driver *driver)
-{
- struct host1x_device *device;
- int err;
-
- mutex_lock(&host1x->devices_lock);
-
- list_for_each_entry(device, &host1x->devices, list) {
- if (device->driver == driver) {
- mutex_unlock(&host1x->devices_lock);
- return;
- }
- }
-
- mutex_unlock(&host1x->devices_lock);
-
- err = host1x_device_add(host1x, driver);
- if (err < 0)
- dev_err(host1x->dev, "failed to allocate device: %d\n", err);
-}
-
-static void host1x_detach_driver(struct host1x *host1x,
- struct host1x_driver *driver)
-{
- struct host1x_device *device, *tmp;
-
- mutex_lock(&host1x->devices_lock);
-
- list_for_each_entry_safe(device, tmp, &host1x->devices, list)
- if (device->driver == driver)
- host1x_device_del(host1x, device);
-
- mutex_unlock(&host1x->devices_lock);
-}
-
-int host1x_register(struct host1x *host1x)
-{
- struct host1x_driver *driver;
-
- mutex_lock(&devices_lock);
- list_add_tail(&host1x->list, &devices);
- mutex_unlock(&devices_lock);
-
- mutex_lock(&drivers_lock);
-
- list_for_each_entry(driver, &drivers, list)
- host1x_attach_driver(host1x, driver);
-
- mutex_unlock(&drivers_lock);
-
- return 0;
-}
-
-int host1x_unregister(struct host1x *host1x)
-{
- struct host1x_driver *driver;
-
- mutex_lock(&drivers_lock);
-
- list_for_each_entry(driver, &drivers, list)
- host1x_detach_driver(host1x, driver);
-
- mutex_unlock(&drivers_lock);
-
- mutex_lock(&devices_lock);
- list_del_init(&host1x->list);
- mutex_unlock(&devices_lock);
-
- return 0;
-}
-
-int host1x_driver_register(struct host1x_driver *driver)
-{
- struct host1x *host1x;
-
- INIT_LIST_HEAD(&driver->list);
-
- mutex_lock(&drivers_lock);
- list_add_tail(&driver->list, &drivers);
- mutex_unlock(&drivers_lock);
-
- mutex_lock(&devices_lock);
-
- list_for_each_entry(host1x, &devices, list)
- host1x_attach_driver(host1x, driver);
-
- mutex_unlock(&devices_lock);
-
- return 0;
-}
-EXPORT_SYMBOL(host1x_driver_register);
-
-void host1x_driver_unregister(struct host1x_driver *driver)
-{
- mutex_lock(&drivers_lock);
- list_del_init(&driver->list);
- mutex_unlock(&drivers_lock);
-}
-EXPORT_SYMBOL(host1x_driver_unregister);
-
-int host1x_client_register(struct host1x_client *client)
-{
- struct host1x *host1x;
- int err;
-
- mutex_lock(&devices_lock);
-
- list_for_each_entry(host1x, &devices, list) {
- err = host1x_register_client(host1x, client);
- if (!err) {
- mutex_unlock(&devices_lock);
- return 0;
- }
- }
-
- mutex_unlock(&devices_lock);
-
- mutex_lock(&clients_lock);
- list_add_tail(&client->list, &clients);
- mutex_unlock(&clients_lock);
-
- return 0;
-}
-EXPORT_SYMBOL(host1x_client_register);
-
-int host1x_client_unregister(struct host1x_client *client)
-{
- struct host1x_client *c;
- struct host1x *host1x;
- int err;
-
- mutex_lock(&devices_lock);
-
- list_for_each_entry(host1x, &devices, list) {
- err = host1x_unregister_client(host1x, client);
- if (!err) {
- mutex_unlock(&devices_lock);
- return 0;
- }
- }
-
- mutex_unlock(&devices_lock);
- mutex_lock(&clients_lock);
-
- list_for_each_entry(c, &clients, list) {
- if (c == client) {
- list_del_init(&c->list);
- break;
- }
- }
-
- mutex_unlock(&clients_lock);
-
- return 0;
-}
-EXPORT_SYMBOL(host1x_client_unregister);
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 3995255..de72172 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -20,7 +20,6 @@
#include <asm/cacheflush.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
-#include <linux/host1x.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/kfifo.h>
@@ -31,6 +30,7 @@
#include "channel.h"
#include "dev.h"
#include "debug.h"
+#include "host1x_bo.h"
#include "job.h"
/*
diff --git a/drivers/gpu/host1x/channel.h b/drivers/gpu/host1x/channel.h
index df767cf..48723b8 100644
--- a/drivers/gpu/host1x/channel.h
+++ b/drivers/gpu/host1x/channel.h
@@ -40,6 +40,12 @@ struct host1x_channel {
/* channel list operations */
int host1x_channel_list_init(struct host1x *host);
+struct host1x_channel *host1x_channel_request(struct device *dev);
+void host1x_channel_free(struct host1x_channel *channel);
+struct host1x_channel *host1x_channel_get(struct host1x_channel *channel);
+void host1x_channel_put(struct host1x_channel *channel);
+int host1x_job_submit(struct host1x_job *job);
+
#define host1x_for_each_channel(host, channel) \
list_for_each_entry(channel, &host->chlist.list, list)
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 80da003..4716302 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -27,13 +27,24 @@
#define CREATE_TRACE_POINTS
#include <trace/events/host1x.h>
-#include "bus.h"
#include "dev.h"
#include "intr.h"
#include "channel.h"
#include "debug.h"
#include "hw/host1x01.h"
-#include "hw/host1x02.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+ struct host1x *host1x = dev_get_drvdata(dev);
+ host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+ struct host1x *host1x = dev_get_drvdata(dev);
+ return host1x ? host1x->drm_data : NULL;
+}
void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
{
@@ -68,17 +79,7 @@ static const struct host1x_info host1x01_info = {
.sync_offset = 0x3000,
};
-static const struct host1x_info host1x02_info = {
- .nb_channels = 9,
- .nb_pts = 32,
- .nb_mlocks = 16,
- .nb_bases = 12,
- .init = host1x02_init,
- .sync_offset = 0x3000,
-};
-
static struct of_device_id host1x_of_match[] = {
- { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, },
{ .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
{ .compatible = "nvidia,tegra20-host1x", .data = &host1x01_info, },
{ },
@@ -113,9 +114,6 @@ static int host1x_probe(struct platform_device *pdev)
if (!host)
return -ENOMEM;
- mutex_init(&host->devices_lock);
- INIT_LIST_HEAD(&host->devices);
- INIT_LIST_HEAD(&host->list);
host->dev = &pdev->dev;
host->info = id->data;
@@ -154,7 +152,7 @@ static int host1x_probe(struct platform_device *pdev)
err = host1x_syncpt_init(host);
if (err) {
dev_err(&pdev->dev, "failed to initialize syncpts\n");
- goto fail_unprepare_disable;
+ return err;
}
err = host1x_intr_init(host, syncpt_irq);
@@ -165,26 +163,19 @@ static int host1x_probe(struct platform_device *pdev)
host1x_debug_init(host);
- err = host1x_register(host);
- if (err < 0)
- goto fail_deinit_intr;
+ host1x_drm_alloc(pdev);
return 0;
-fail_deinit_intr:
- host1x_intr_deinit(host);
fail_deinit_syncpt:
host1x_syncpt_deinit(host);
-fail_unprepare_disable:
- clk_disable_unprepare(host->clk);
return err;
}
-static int host1x_remove(struct platform_device *pdev)
+static int __exit host1x_remove(struct platform_device *pdev)
{
struct host1x *host = platform_get_drvdata(pdev);
- host1x_unregister(host);
host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
@@ -193,36 +184,59 @@ static int host1x_remove(struct platform_device *pdev)
}
static struct platform_driver tegra_host1x_driver = {
+ .probe = host1x_probe,
+ .remove = __exit_p(host1x_remove),
.driver = {
+ .owner = THIS_MODULE,
.name = "tegra-host1x",
.of_match_table = host1x_of_match,
},
- .probe = host1x_probe,
- .remove = host1x_remove,
};
static int __init tegra_host1x_init(void)
{
int err;
- err = host1x_bus_init();
+ err = platform_driver_register(&tegra_host1x_driver);
if (err < 0)
return err;
- err = platform_driver_register(&tegra_host1x_driver);
- if (err < 0) {
- host1x_bus_exit();
- return err;
- }
+#ifdef CONFIG_DRM_TEGRA
+ err = platform_driver_register(&tegra_dc_driver);
+ if (err < 0)
+ goto unregister_host1x;
+
+ err = platform_driver_register(&tegra_hdmi_driver);
+ if (err < 0)
+ goto unregister_dc;
+
+ err = platform_driver_register(&tegra_gr2d_driver);
+ if (err < 0)
+ goto unregister_hdmi;
+#endif
return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+ platform_driver_unregister(&tegra_hdmi_driver);
+unregister_dc:
+ platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+ platform_driver_unregister(&tegra_host1x_driver);
+ return err;
+#endif
}
module_init(tegra_host1x_init);
static void __exit tegra_host1x_exit(void)
{
+#ifdef CONFIG_DRM_TEGRA
+ platform_driver_unregister(&tegra_gr2d_driver);
+ platform_driver_unregister(&tegra_hdmi_driver);
+ platform_driver_unregister(&tegra_dc_driver);
+#endif
platform_driver_unregister(&tegra_host1x_driver);
- host1x_bus_exit();
}
module_exit(tegra_host1x_exit);
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index a61a976..bed90a8 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -27,7 +27,6 @@
#include "job.h"
struct host1x_syncpt;
-struct host1x_syncpt_base;
struct host1x_channel;
struct host1x_cdma;
struct host1x_job;
@@ -103,7 +102,6 @@ struct host1x {
void __iomem *regs;
struct host1x_syncpt *syncpt;
- struct host1x_syncpt_base *bases;
struct device *dev;
struct clk *clk;
@@ -127,10 +125,7 @@ struct host1x {
struct dentry *debugfs;
- struct mutex devices_lock;
- struct list_head devices;
-
- struct list_head list;
+ void *drm_data;
};
void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -306,4 +301,8 @@ static inline void host1x_hw_show_mlocks(struct host1x *host, struct output *o)
host->debug_op->show_mlocks(host, o);
}
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
#endif
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index 8961ba6..69853a4 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,10 +1,7 @@
config DRM_TEGRA
bool "NVIDIA Tegra DRM"
- depends on ARCH_TEGRA || ARCH_MULTIPLATFORM
depends on DRM
- select TEGRA_HOST1X
select DRM_KMS_HELPER
- select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
@@ -16,11 +13,6 @@ config DRM_TEGRA
if DRM_TEGRA
-config DRM_TEGRA_DEBUG
- bool "NVIDIA Tegra DRM debug support"
- help
- Say yes here to enable debugging support.
-
config DRM_TEGRA_STAGING
bool "Enable HOST1X interface"
depends on STAGING
@@ -29,4 +21,9 @@ config DRM_TEGRA_STAGING
If unsure, choose N.
+config DRM_TEGRA_DEBUG
+ bool "NVIDIA Tegra DRM debug support"
+ help
+ Say yes here to enable debugging support.
+
endif
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
index ae1cb31..b1a05ad 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -8,9 +8,13 @@
*/
#include <linux/clk.h>
-#include <linux/clk/tegra.h>
#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/clk/tegra.h>
+#include "host1x_client.h"
#include "dc.h"
#include "drm.h"
#include "gem.h"
@@ -47,8 +51,6 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
window.dst.h = crtc_h;
window.format = tegra_dc_format(fb->pixel_format);
window.bits_per_pixel = fb->bits_per_pixel;
- window.bottom_up = tegra_fb_is_bottom_up(fb);
- window.tiled = tegra_fb_is_tiled(fb);
for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
@@ -95,11 +97,8 @@ static int tegra_plane_disable(struct drm_plane *plane)
static void tegra_plane_destroy(struct drm_plane *plane)
{
- struct tegra_plane *p = to_tegra_plane(plane);
-
tegra_plane_disable(plane);
drm_plane_cleanup(plane);
- kfree(p);
}
static const struct drm_plane_funcs tegra_plane_funcs = {
@@ -125,7 +124,7 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
for (i = 0; i < 2; i++) {
struct tegra_plane *plane;
- plane = kzalloc(sizeof(*plane), GFP_KERNEL);
+ plane = devm_kzalloc(drm->dev, sizeof(*plane), GFP_KERNEL);
if (!plane)
return -ENOMEM;
@@ -134,10 +133,8 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
err = drm_plane_init(drm, &plane->base, 1 << dc->pipe,
&tegra_plane_funcs, plane_formats,
ARRAY_SIZE(plane_formats), false);
- if (err < 0) {
- kfree(plane);
+ if (err < 0)
return err;
- }
}
return 0;
@@ -148,7 +145,6 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
{
unsigned int format = tegra_dc_format(fb->pixel_format);
struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
- unsigned int h_offset = 0, v_offset = 0;
unsigned long value;
tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -160,32 +156,6 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);
- if (tegra_fb_is_tiled(fb)) {
- value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
- DC_WIN_BUFFER_ADDR_MODE_TILE;
- } else {
- value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
- DC_WIN_BUFFER_ADDR_MODE_LINEAR;
- }
-
- tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
-
- /* make sure bottom-up buffers are properly displayed */
- if (tegra_fb_is_bottom_up(fb)) {
- value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
- value |= INVERT_V;
- tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
-
- v_offset += fb->height - 1;
- } else {
- value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
- value &= ~INVERT_V;
- tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
- }
-
- tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
- tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
-
value = GENERAL_UPDATE | WIN_A_UPDATE;
tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
@@ -285,26 +255,14 @@ static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
return 0;
}
-static void drm_crtc_clear(struct drm_crtc *crtc)
-{
- memset(crtc, 0, sizeof(*crtc));
-}
-
-static void tegra_dc_destroy(struct drm_crtc *crtc)
-{
- drm_crtc_cleanup(crtc);
- drm_crtc_clear(crtc);
-}
-
static const struct drm_crtc_funcs tegra_crtc_funcs = {
.page_flip = tegra_dc_page_flip,
.set_config = drm_crtc_helper_set_config,
- .destroy = tegra_dc_destroy,
+ .destroy = drm_crtc_cleanup,
};
static void tegra_crtc_disable(struct drm_crtc *crtc)
{
- struct tegra_dc *dc = to_tegra_dc(crtc);
struct drm_device *drm = crtc->dev;
struct drm_plane *plane;
@@ -319,8 +277,6 @@ static void tegra_crtc_disable(struct drm_crtc *crtc)
}
}
}
-
- drm_vblank_off(drm, dc->pipe);
}
static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -535,22 +491,9 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
}
- if (window->bottom_up)
- v_offset += window->src.h - 1;
-
tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
- if (window->tiled) {
- value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
- DC_WIN_BUFFER_ADDR_MODE_TILE;
- } else {
- value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
- DC_WIN_BUFFER_ADDR_MODE_LINEAR;
- }
-
- tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
-
value = WIN_ENABLE;
if (yuv) {
@@ -569,9 +512,6 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
value |= COLOR_EXPAND;
}
- if (window->bottom_up)
- value |= INVERT_V;
-
tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
/*
@@ -1101,30 +1041,30 @@ static int tegra_dc_debugfs_exit(struct tegra_dc *dc)
return 0;
}
-static int tegra_dc_init(struct host1x_client *client)
+static int tegra_dc_drm_init(struct host1x_client *client,
+ struct drm_device *drm)
{
- struct tegra_drm *tegra = dev_get_drvdata(client->parent);
struct tegra_dc *dc = host1x_client_to_dc(client);
int err;
- dc->pipe = tegra->drm->mode_config.num_crtc;
+ dc->pipe = drm->mode_config.num_crtc;
- drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs);
+ drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs);
drm_mode_crtc_set_gamma_size(&dc->base, 256);
drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
- err = tegra_dc_rgb_init(tegra->drm, dc);
+ err = tegra_dc_rgb_init(drm, dc);
if (err < 0 && err != -ENODEV) {
dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
return err;
}
- err = tegra_dc_add_planes(tegra->drm, dc);
+ err = tegra_dc_add_planes(drm, dc);
if (err < 0)
return err;
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
- err = tegra_dc_debugfs_init(dc, tegra->drm->primary);
+ err = tegra_dc_debugfs_init(dc, drm->primary);
if (err < 0)
dev_err(dc->dev, "debugfs setup failed: %d\n", err);
}
@@ -1140,7 +1080,7 @@ static int tegra_dc_init(struct host1x_client *client)
return 0;
}
-static int tegra_dc_exit(struct host1x_client *client)
+static int tegra_dc_drm_exit(struct host1x_client *client)
{
struct tegra_dc *dc = host1x_client_to_dc(client);
int err;
@@ -1163,12 +1103,13 @@ static int tegra_dc_exit(struct host1x_client *client)
}
static const struct host1x_client_ops dc_client_ops = {
- .init = tegra_dc_init,
- .exit = tegra_dc_exit,
+ .drm_init = tegra_dc_drm_init,
+ .drm_exit = tegra_dc_drm_exit,
};
static int tegra_dc_probe(struct platform_device *pdev)
{
+ struct host1x_drm *host1x = host1x_get_drm_data(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1212,7 +1153,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
return err;
}
- err = host1x_client_register(&dc->client);
+ err = host1x_register_client(host1x, &dc->client);
if (err < 0) {
dev_err(&pdev->dev, "failed to register host1x client: %d\n",
err);
@@ -1226,22 +1167,17 @@ static int tegra_dc_probe(struct platform_device *pdev)
static int tegra_dc_remove(struct platform_device *pdev)
{
+ struct host1x_drm *host1x = host1x_get_drm_data(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;
- err = host1x_client_unregister(&dc->client);
+ err = host1x_unregister_client(host1x, &dc->client);
if (err < 0) {
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
err);
return err;
}
- err = tegra_dc_rgb_remove(dc);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to remove RGB output: %d\n", err);
- return err;
- }
-
clk_disable_unprepare(dc->clk);
return 0;
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
index 91bbda2..79eaec9 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/host1x/drm/dc.h
@@ -302,7 +302,6 @@
#define DC_WIN_CSC_KVB 0x618
#define DC_WIN_WIN_OPTIONS 0x700
-#define INVERT_V (1 << 2)
#define COLOR_EXPAND (1 << 6)
#define CSC_ENABLE (1 << 18)
#define WIN_ENABLE (1 << 30)
@@ -366,10 +365,6 @@
#define DC_WIN_BUF_STRIDE 0x70b
#define DC_WIN_UV_BUF_STRIDE 0x70c
#define DC_WIN_BUFFER_ADDR_MODE 0x70d
-#define DC_WIN_BUFFER_ADDR_MODE_LINEAR (0 << 0)
-#define DC_WIN_BUFFER_ADDR_MODE_TILE (1 << 0)
-#define DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV (0 << 16)
-#define DC_WIN_BUFFER_ADDR_MODE_TILE_UV (1 << 16)
#define DC_WIN_DV_CONTROL 0x70e
#define DC_WIN_BLEND_NOKEY 0x70f
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
new file mode 100644
index 0000000..8c61cee
--- /dev/null
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include <linux/dma-mapping.h>
+#include <asm/dma-iommu.h>
+
+#include <drm/drm.h>
+#include <drm/drmP.h>
+
+#include "host1x_client.h"
+#include "dev.h"
+#include "drm.h"
+#include "gem.h"
+#include "syncpt.h"
+
+#define DRIVER_NAME "tegra"
+#define DRIVER_DESC "NVIDIA Tegra graphics"
+#define DRIVER_DATE "20120330"
+#define DRIVER_MAJOR 0
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+struct host1x_drm_client {
+ struct host1x_client *client;
+ struct device_node *np;
+ struct list_head list;
+};
+
+static int host1x_add_drm_client(struct host1x_drm *host1x,
+ struct device_node *np)
+{
+ struct host1x_drm_client *client;
+
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
+ if (!client)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&client->list);
+ client->np = of_node_get(np);
+
+ list_add_tail(&client->list, &host1x->drm_clients);
+
+ return 0;
+}
+
+static int host1x_activate_drm_client(struct host1x_drm *host1x,
+ struct host1x_drm_client *drm,
+ struct host1x_client *client)
+{
+ mutex_lock(&host1x->drm_clients_lock);
+ list_del_init(&drm->list);
+ list_add_tail(&drm->list, &host1x->drm_active);
+ drm->client = client;
+ mutex_unlock(&host1x->drm_clients_lock);
+
+ return 0;
+}
+
+static int host1x_remove_drm_client(struct host1x_drm *host1x,
+ struct host1x_drm_client *client)
+{
+ mutex_lock(&host1x->drm_clients_lock);
+ list_del_init(&client->list);
+ mutex_unlock(&host1x->drm_clients_lock);
+
+ of_node_put(client->np);
+ kfree(client);
+
+ return 0;
+}
+
+static int host1x_parse_dt(struct host1x_drm *host1x)
+{
+ static const char * const compat[] = {
+ "nvidia,tegra20-dc",
+ "nvidia,tegra20-hdmi",
+ "nvidia,tegra20-gr2d",
+ "nvidia,tegra30-dc",
+ "nvidia,tegra30-hdmi",
+ "nvidia,tegra30-gr2d",
+ };
+ unsigned int i;
+ int err;
+
+ for (i = 0; i < ARRAY_SIZE(compat); i++) {
+ struct device_node *np;
+
+ for_each_child_of_node(host1x->dev->of_node, np) {
+ if (of_device_is_compatible(np, compat[i]) &&
+ of_device_is_available(np)) {
+ err = host1x_add_drm_client(host1x, np);
+ if (err < 0)
+ return err;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int host1x_drm_alloc(struct platform_device *pdev)
+{
+ struct host1x_drm *host1x;
+ int err;
+
+ host1x = devm_kzalloc(&pdev->dev, sizeof(*host1x), GFP_KERNEL);
+ if (!host1x)
+ return -ENOMEM;
+
+ mutex_init(&host1x->drm_clients_lock);
+ INIT_LIST_HEAD(&host1x->drm_clients);
+ INIT_LIST_HEAD(&host1x->drm_active);
+ mutex_init(&host1x->clients_lock);
+ INIT_LIST_HEAD(&host1x->clients);
+ host1x->dev = &pdev->dev;
+
+ err = host1x_parse_dt(host1x);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to parse DT: %d\n", err);
+ return err;
+ }
+
+ host1x_set_drm_data(&pdev->dev, host1x);
+
+ return 0;
+}
+
+int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm)
+{
+ struct host1x_client *client;
+
+ mutex_lock(&host1x->clients_lock);
+
+ list_for_each_entry(client, &host1x->clients, list) {
+ if (client->ops && client->ops->drm_init) {
+ int err = client->ops->drm_init(client, drm);
+ if (err < 0) {
+ dev_err(host1x->dev,
+ "DRM setup failed for %s: %d\n",
+ dev_name(client->dev), err);
+ mutex_unlock(&host1x->clients_lock);
+ return err;
+ }
+ }
+ }
+
+ mutex_unlock(&host1x->clients_lock);
+
+ return 0;
+}
+
+int host1x_drm_exit(struct host1x_drm *host1x)
+{
+ struct platform_device *pdev = to_platform_device(host1x->dev);
+ struct host1x_client *client;
+
+ if (!host1x->drm)
+ return 0;
+
+ mutex_lock(&host1x->clients_lock);
+
+ list_for_each_entry_reverse(client, &host1x->clients, list) {
+ if (client->ops && client->ops->drm_exit) {
+ int err = client->ops->drm_exit(client);
+ if (err < 0) {
+ dev_err(host1x->dev,
+ "DRM cleanup failed for %s: %d\n",
+ dev_name(client->dev), err);
+ mutex_unlock(&host1x->clients_lock);
+ return err;
+ }
+ }
+ }
+
+ mutex_unlock(&host1x->clients_lock);
+
+ drm_platform_exit(&tegra_drm_driver, pdev);
+ host1x->drm = NULL;
+
+ return 0;
+}
+
+int host1x_register_client(struct host1x_drm *host1x,
+ struct host1x_client *client)
+{
+ struct host1x_drm_client *drm, *tmp;
+ int err;
+
+ mutex_lock(&host1x->clients_lock);
+ list_add_tail(&client->list, &host1x->clients);
+ mutex_unlock(&host1x->clients_lock);
+
+ list_for_each_entry_safe(drm, tmp, &host1x->drm_clients, list)
+ if (drm->np == client->dev->of_node)
+ host1x_activate_drm_client(host1x, drm, client);
+
+ if (list_empty(&host1x->drm_clients)) {
+ struct platform_device *pdev = to_platform_device(host1x->dev);
+
+ err = drm_platform_init(&tegra_drm_driver, pdev);
+ if (err < 0) {
+ dev_err(host1x->dev, "drm_platform_init(): %d\n", err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+int host1x_unregister_client(struct host1x_drm *host1x,
+ struct host1x_client *client)
+{
+ struct host1x_drm_client *drm, *tmp;
+ int err;
+
+ list_for_each_entry_safe(drm, tmp, &host1x->drm_active, list) {
+ if (drm->client == client) {
+ err = host1x_drm_exit(host1x);
+ if (err < 0) {
+ dev_err(host1x->dev, "host1x_drm_exit(): %d\n",
+ err);
+ return err;
+ }
+
+ host1x_remove_drm_client(host1x, drm);
+ break;
+ }
+ }
+
+ mutex_lock(&host1x->clients_lock);
+ list_del_init(&client->list);
+ mutex_unlock(&host1x->clients_lock);
+
+ return 0;
+}
+
+static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
+{
+ struct host1x_drm *host1x;
+ int err;
+
+ host1x = host1x_get_drm_data(drm->dev);
+ drm->dev_private = host1x;
+ host1x->drm = drm;
+
+ drm_mode_config_init(drm);
+
+ err = host1x_drm_init(host1x, drm);
+ if (err < 0)
+ return err;
+
+ /*
+ * We don't use the drm_irq_install() helpers provided by the DRM
+ * core, so we need to set this manually in order to allow the
+ * DRM_IOCTL_WAIT_VBLANK to operate correctly.
+ */
+ drm->irq_enabled = 1;
+
+ err = drm_vblank_init(drm, drm->mode_config.num_crtc);
+ if (err < 0)
+ return err;
+
+ err = tegra_drm_fb_init(drm);
+ if (err < 0)
+ return err;
+
+ drm_kms_helper_poll_init(drm);
+
+ return 0;
+}
+
+static int tegra_drm_unload(struct drm_device *drm)
+{
+ drm_kms_helper_poll_fini(drm);
+ tegra_drm_fb_exit(drm);
+
+ drm_mode_config_cleanup(drm);
+
+ return 0;
+}
+
+static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
+{
+ struct host1x_drm_file *fpriv;
+
+ fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+ if (!fpriv)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&fpriv->contexts);
+ filp->driver_priv = fpriv;
+
+ return 0;
+}
+
+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+ context->client->ops->close_channel(context);
+ kfree(context);
+}
+
+static void tegra_drm_lastclose(struct drm_device *drm)
+{
+ struct host1x_drm *host1x = drm->dev_private;
+
+ tegra_fbdev_restore_mode(host1x->fbdev);
+}
+
+#ifdef CONFIG_DRM_TEGRA_STAGING
+static bool host1x_drm_file_owns_context(struct host1x_drm_file *file,
+ struct host1x_drm_context *context)
+{
+ struct host1x_drm_context *ctx;
+
+ list_for_each_entry(ctx, &file->contexts, list)
+ if (ctx == context)
+ return true;
+
+ return false;
+}
+
+static int tegra_gem_create(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_gem_create *args = data;
+ struct tegra_bo *bo;
+
+ bo = tegra_bo_create_with_handle(file, drm, args->size,
+ &args->handle);
+ if (IS_ERR(bo))
+ return PTR_ERR(bo);
+
+ return 0;
+}
+
+static int tegra_gem_mmap(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_gem_mmap *args = data;
+ struct drm_gem_object *gem;
+ struct tegra_bo *bo;
+
+ gem = drm_gem_object_lookup(drm, file, args->handle);
+ if (!gem)
+ return -EINVAL;
+
+ bo = to_tegra_bo(gem);
+
+ args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
+
+ drm_gem_object_unreference(gem);
+
+ return 0;
+}
+
+static int tegra_syncpt_read(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_syncpt_read *args = data;
+ struct host1x *host = dev_get_drvdata(drm->dev);
+ struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id);
+
+ if (!sp)
+ return -EINVAL;
+
+ args->value = host1x_syncpt_read_min(sp);
+ return 0;
+}
+
+static int tegra_syncpt_incr(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_syncpt_incr *args = data;
+ struct host1x *host = dev_get_drvdata(drm->dev);
+ struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id);
+
+ if (!sp)
+ return -EINVAL;
+
+ return host1x_syncpt_incr(sp);
+}
+
+static int tegra_syncpt_wait(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_syncpt_wait *args = data;
+ struct host1x *host = dev_get_drvdata(drm->dev);
+ struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id);
+
+ if (!sp)
+ return -EINVAL;
+
+ return host1x_syncpt_wait(sp, args->thresh, args->timeout,
+ &args->value);
+}
+
+static int tegra_open_channel(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_open_channel *args = data;
+ struct host1x_client *client;
+ struct host1x_drm_context *context;
+ struct host1x_drm_file *fpriv = file->driver_priv;
+ struct host1x_drm *host1x = drm->dev_private;
+ int err = -ENODEV;
+
+ context = kzalloc(sizeof(*context), GFP_KERNEL);
+ if (!context)
+ return -ENOMEM;
+
+ list_for_each_entry(client, &host1x->clients, list)
+ if (client->class == args->client) {
+ err = client->ops->open_channel(client, context);
+ if (err)
+ break;
+
+ context->client = client;
+ list_add(&context->list, &fpriv->contexts);
+ args->context = (uintptr_t)context;
+ return 0;
+ }
+
+ kfree(context);
+ return err;
+}
+
+static int tegra_close_channel(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_close_channel *args = data;
+ struct host1x_drm_file *fpriv = file->driver_priv;
+ struct host1x_drm_context *context =
+ (struct host1x_drm_context *)(uintptr_t)args->context;
+
+ if (!host1x_drm_file_owns_context(fpriv, context))
+ return -EINVAL;
+
+ list_del(&context->list);
+ host1x_drm_context_free(context);
+
+ return 0;
+}
+
+static int tegra_get_syncpt(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_get_syncpt *args = data;
+ struct host1x_drm_file *fpriv = file->driver_priv;
+ struct host1x_drm_context *context =
+ (struct host1x_drm_context *)(uintptr_t)args->context;
+ struct host1x_syncpt *syncpt;
+
+ if (!host1x_drm_file_owns_context(fpriv, context))
+ return -ENODEV;
+
+ if (args->index >= context->client->num_syncpts)
+ return -EINVAL;
+
+ syncpt = context->client->syncpts[args->index];
+ args->id = host1x_syncpt_id(syncpt);
+
+ return 0;
+}
+
+static int tegra_submit(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_submit *args = data;
+ struct host1x_drm_file *fpriv = file->driver_priv;
+ struct host1x_drm_context *context =
+ (struct host1x_drm_context *)(uintptr_t)args->context;
+
+ if (!host1x_drm_file_owns_context(fpriv, context))
+ return -ENODEV;
+
+ return context->client->ops->submit(context, args, drm, file);
+}
+#endif
+
+static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
+#ifdef CONFIG_DRM_TEGRA_STAGING
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_UNLOCKED | DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, DRM_UNLOCKED),
+#endif
+};
+
+static const struct file_operations tegra_drm_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = tegra_drm_mmap,
+ .poll = drm_poll,
+ .read = drm_read,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .llseek = noop_llseek,
+};
+
+static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe)
+{
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) {
+ struct tegra_dc *dc = to_tegra_dc(crtc);
+
+ if (dc->pipe == pipe)
+ return crtc;
+ }
+
+ return NULL;
+}
+
+static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ /* TODO: implement real hardware counter using syncpoints */
+ return drm_vblank_count(dev, crtc);
+}
+
+static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)
+{
+ struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
+ struct tegra_dc *dc = to_tegra_dc(crtc);
+
+ if (!crtc)
+ return -ENODEV;
+
+ tegra_dc_enable_vblank(dc);
+
+ return 0;
+}
+
+static void tegra_drm_disable_vblank(struct drm_device *drm, int pipe)
+{
+ struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
+ struct tegra_dc *dc = to_tegra_dc(crtc);
+
+ if (crtc)
+ tegra_dc_disable_vblank(dc);
+}
+
+static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file)
+{
+ struct host1x_drm_file *fpriv = file->driver_priv;
+ struct host1x_drm_context *context, *tmp;
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
+ tegra_dc_cancel_page_flip(crtc, file);
+
+ list_for_each_entry_safe(context, tmp, &fpriv->contexts, list)
+ host1x_drm_context_free(context);
+
+ kfree(fpriv);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int tegra_debugfs_framebuffers(struct seq_file *s, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *)s->private;
+ struct drm_device *drm = node->minor->dev;
+ struct drm_framebuffer *fb;
+
+ mutex_lock(&drm->mode_config.fb_lock);
+
+ list_for_each_entry(fb, &drm->mode_config.fb_list, head) {
+ seq_printf(s, "%3d: user size: %d x %d, depth %d, %d bpp, refcount %d\n",
+ fb->base.id, fb->width, fb->height, fb->depth,
+ fb->bits_per_pixel,
+ atomic_read(&fb->refcount.refcount));
+ }
+
+ mutex_unlock(&drm->mode_config.fb_lock);
+
+ return 0;
+}
+
+static struct drm_info_list tegra_debugfs_list[] = {
+ { "framebuffers", tegra_debugfs_framebuffers, 0 },
+};
+
+static int tegra_debugfs_init(struct drm_minor *minor)
+{
+ return drm_debugfs_create_files(tegra_debugfs_list,
+ ARRAY_SIZE(tegra_debugfs_list),
+ minor->debugfs_root, minor);
+}
+
+static void tegra_debugfs_cleanup(struct drm_minor *minor)
+{
+ drm_debugfs_remove_files(tegra_debugfs_list,
+ ARRAY_SIZE(tegra_debugfs_list), minor);
+}
+#endif
+
+struct drm_driver tegra_drm_driver = {
+ .driver_features = DRIVER_MODESET | DRIVER_GEM,
+ .load = tegra_drm_load,
+ .unload = tegra_drm_unload,
+ .open = tegra_drm_open,
+ .preclose = tegra_drm_preclose,
+ .lastclose = tegra_drm_lastclose,
+
+ .get_vblank_counter = tegra_drm_get_vblank_counter,
+ .enable_vblank = tegra_drm_enable_vblank,
+ .disable_vblank = tegra_drm_disable_vblank,
+
+#if defined(CONFIG_DEBUG_FS)
+ .debugfs_init = tegra_debugfs_init,
+ .debugfs_cleanup = tegra_debugfs_cleanup,
+#endif
+
+ .gem_free_object = tegra_bo_free_object,
+ .gem_vm_ops = &tegra_bo_vm_ops,
+ .dumb_create = tegra_bo_dumb_create,
+ .dumb_map_offset = tegra_bo_dumb_map_offset,
+ .dumb_destroy = drm_gem_dumb_destroy,
+
+ .ioctls = tegra_drm_ioctls,
+ .num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
+ .fops = &tegra_drm_fops,
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+};
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
index 7da0b92..02ce020 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -10,14 +10,14 @@
#ifndef HOST1X_DRM_H
#define HOST1X_DRM_H 1
-#include <uapi/drm/tegra_drm.h>
-#include <linux/host1x.h>
-
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fixed.h>
+#include <uapi/drm/tegra_drm.h>
+
+#include "host1x.h"
struct tegra_fb {
struct drm_framebuffer base;
@@ -30,8 +30,17 @@ struct tegra_fbdev {
struct tegra_fb *fb;
};
-struct tegra_drm {
+struct host1x_drm {
struct drm_device *drm;
+ struct device *dev;
+ void __iomem *regs;
+ struct clk *clk;
+ int syncpt;
+ int irq;
+
+ struct mutex drm_clients_lock;
+ struct list_head drm_clients;
+ struct list_head drm_active;
struct mutex clients_lock;
struct list_head clients;
@@ -39,60 +48,66 @@ struct tegra_drm {
struct tegra_fbdev *fbdev;
};
-struct tegra_drm_client;
+struct host1x_client;
-struct tegra_drm_context {
- struct tegra_drm_client *client;
+struct host1x_drm_context {
+ struct host1x_client *client;
struct host1x_channel *channel;
struct list_head list;
};
-struct tegra_drm_client_ops {
- int (*open_channel)(struct tegra_drm_client *client,
- struct tegra_drm_context *context);
- void (*close_channel)(struct tegra_drm_context *context);
- int (*is_addr_reg)(struct device *dev, u32 class, u32 offset);
- int (*submit)(struct tegra_drm_context *context,
+struct host1x_client_ops {
+ int (*drm_init)(struct host1x_client *client, struct drm_device *drm);
+ int (*drm_exit)(struct host1x_client *client);
+ int (*open_channel)(struct host1x_client *client,
+ struct host1x_drm_context *context);
+ void (*close_channel)(struct host1x_drm_context *context);
+ int (*submit)(struct host1x_drm_context *context,
struct drm_tegra_submit *args, struct drm_device *drm,
struct drm_file *file);
};
-int tegra_drm_submit(struct tegra_drm_context *context,
- struct drm_tegra_submit *args, struct drm_device *drm,
- struct drm_file *file);
+struct host1x_drm_file {
+ struct list_head contexts;
+};
-struct tegra_drm_client {
- struct host1x_client base;
- struct list_head list;
+struct host1x_client {
+ struct host1x_drm *host1x;
+ struct device *dev;
- const struct tegra_drm_client_ops *ops;
-};
+ const struct host1x_client_ops *ops;
-static inline struct tegra_drm_client *
-host1x_to_drm_client(struct host1x_client *client)
-{
- return container_of(client, struct tegra_drm_client, base);
-}
+ enum host1x_class class;
+ struct host1x_channel *channel;
+
+ struct host1x_syncpt **syncpts;
+ unsigned int num_syncpts;
+
+ struct list_head list;
+};
-extern int tegra_drm_register_client(struct tegra_drm *tegra,
- struct tegra_drm_client *client);
-extern int tegra_drm_unregister_client(struct tegra_drm *tegra,
- struct tegra_drm_client *client);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);
-extern int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm);
-extern int tegra_drm_exit(struct tegra_drm *tegra);
+extern int host1x_register_client(struct host1x_drm *host1x,
+ struct host1x_client *client);
+extern int host1x_unregister_client(struct host1x_drm *host1x,
+ struct host1x_client *client);
struct tegra_output;
struct tegra_dc {
struct host1x_client client;
- struct device *dev;
spinlock_t lock;
+ struct host1x_drm *host1x;
+ struct device *dev;
+
struct drm_crtc base;
int pipe;
struct clk *clk;
+
void __iomem *regs;
int irq;
@@ -108,15 +123,14 @@ struct tegra_dc {
struct drm_pending_vblank_event *event;
};
-static inline struct tegra_dc *
-host1x_client_to_dc(struct host1x_client *client)
+static inline struct tegra_dc *host1x_client_to_dc(struct host1x_client *client)
{
return container_of(client, struct tegra_dc, client);
}
static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
{
- return crtc ? container_of(crtc, struct tegra_dc, base) : NULL;
+ return container_of(crtc, struct tegra_dc, base);
}
static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long value,
@@ -148,8 +162,6 @@ struct tegra_dc_window {
unsigned int format;
unsigned int stride[2];
unsigned long base[3];
- bool bottom_up;
- bool tiled;
};
/* from dc.c */
@@ -237,34 +249,23 @@ static inline int tegra_output_check_mode(struct tegra_output *output,
return output ? -ENOSYS : -EINVAL;
}
-/* from bus.c */
-int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device);
-void drm_host1x_exit(struct drm_driver *driver, struct host1x_device *device);
-
/* from rgb.c */
extern int tegra_dc_rgb_probe(struct tegra_dc *dc);
-extern int tegra_dc_rgb_remove(struct tegra_dc *dc);
extern int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc);
extern int tegra_dc_rgb_exit(struct tegra_dc *dc);
/* from output.c */
-extern int tegra_output_probe(struct tegra_output *output);
-extern int tegra_output_remove(struct tegra_output *output);
+extern int tegra_output_parse_dt(struct tegra_output *output);
extern int tegra_output_init(struct drm_device *drm, struct tegra_output *output);
extern int tegra_output_exit(struct tegra_output *output);
/* from fb.c */
struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
unsigned int index);
-bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
-bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer);
extern int tegra_drm_fb_init(struct drm_device *drm);
extern void tegra_drm_fb_exit(struct drm_device *drm);
extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
-extern struct platform_driver tegra_dc_driver;
-extern struct platform_driver tegra_hdmi_driver;
-extern struct platform_driver tegra_gr2d_driver;
-extern struct platform_driver tegra_gr3d_driver;
+extern struct drm_driver tegra_drm_driver;
#endif /* HOST1X_DRM_H */
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/host1x/drm/fb.c
index a3835e7..979a3e3 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -10,6 +10,8 @@
* published by the Free Software Foundation.
*/
+#include <linux/module.h>
+
#include "drm.h"
#include "gem.h"
@@ -34,26 +36,6 @@ struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
return fb->planes[index];
}
-bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer)
-{
- struct tegra_fb *fb = to_tegra_fb(framebuffer);
-
- if (fb->planes[0]->flags & TEGRA_BO_BOTTOM_UP)
- return true;
-
- return false;
-}
-
-bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer)
-{
- struct tegra_fb *fb = to_tegra_fb(framebuffer);
-
- if (fb->planes[0]->flags & TEGRA_BO_TILED)
- return true;
-
- return false;
-}
-
static void tegra_fb_destroy(struct drm_framebuffer *framebuffer)
{
struct tegra_fb *fb = to_tegra_fb(framebuffer);
@@ -208,7 +190,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
size = cmd.pitches[0] * cmd.height;
- bo = tegra_bo_create(drm, size, 0);
+ bo = tegra_bo_create(drm, size);
if (IS_ERR(bo))
return PTR_ERR(bo);
@@ -247,7 +229,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
info->var.yoffset * fb->pitches[0];
drm->mode_config.fb_base = (resource_size_t)bo->paddr;
- info->screen_base = (void __iomem *)bo->vaddr + offset;
+ info->screen_base = bo->vaddr + offset;
info->screen_size = size;
info->fix.smem_start = (unsigned long)(bo->paddr + offset);
info->fix.smem_len = size;
@@ -341,10 +323,10 @@ static void tegra_fbdev_free(struct tegra_fbdev *fbdev)
static void tegra_fb_output_poll_changed(struct drm_device *drm)
{
- struct tegra_drm *tegra = drm->dev_private;
+ struct host1x_drm *host1x = drm->dev_private;
- if (tegra->fbdev)
- drm_fb_helper_hotplug_event(&tegra->fbdev->base);
+ if (host1x->fbdev)
+ drm_fb_helper_hotplug_event(&host1x->fbdev->base);
}
static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
@@ -354,7 +336,7 @@ static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
int tegra_drm_fb_init(struct drm_device *drm)
{
- struct tegra_drm *tegra = drm->dev_private;
+ struct host1x_drm *host1x = drm->dev_private;
struct tegra_fbdev *fbdev;
drm->mode_config.min_width = 0;
@@ -370,16 +352,16 @@ int tegra_drm_fb_init(struct drm_device *drm)
if (IS_ERR(fbdev))
return PTR_ERR(fbdev);
- tegra->fbdev = fbdev;
+ host1x->fbdev = fbdev;
return 0;
}
void tegra_drm_fb_exit(struct drm_device *drm)
{
- struct tegra_drm *tegra = drm->dev_private;
+ struct host1x_drm *host1x = drm->dev_private;
- tegra_fbdev_free(tegra->fbdev);
+ tegra_fbdev_free(host1x->fbdev);
}
void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev)
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/host1x/drm/gem.c
index 28a9cbc..59623de 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/host1x/drm/gem.c
@@ -18,18 +18,25 @@
* GNU General Public License for more details.
*/
-#include <drm/tegra_drm.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/export.h>
+#include <linux/dma-mapping.h>
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
#include "gem.h"
-static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo)
+static inline struct tegra_bo *host1x_to_drm_bo(struct host1x_bo *bo)
{
return container_of(bo, struct tegra_bo, base);
}
static void tegra_bo_put(struct host1x_bo *bo)
{
- struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+ struct tegra_bo *obj = host1x_to_drm_bo(bo);
struct drm_device *drm = obj->gem.dev;
mutex_lock(&drm->struct_mutex);
@@ -39,7 +46,7 @@ static void tegra_bo_put(struct host1x_bo *bo)
static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
{
- struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+ struct tegra_bo *obj = host1x_to_drm_bo(bo);
return obj->paddr;
}
@@ -50,7 +57,7 @@ static void tegra_bo_unpin(struct host1x_bo *bo, struct sg_table *sgt)
static void *tegra_bo_mmap(struct host1x_bo *bo)
{
- struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+ struct tegra_bo *obj = host1x_to_drm_bo(bo);
return obj->vaddr;
}
@@ -61,7 +68,7 @@ static void tegra_bo_munmap(struct host1x_bo *bo, void *addr)
static void *tegra_bo_kmap(struct host1x_bo *bo, unsigned int page)
{
- struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+ struct tegra_bo *obj = host1x_to_drm_bo(bo);
return obj->vaddr + page * PAGE_SIZE;
}
@@ -73,7 +80,7 @@ static void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page,
static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
{
- struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+ struct tegra_bo *obj = host1x_to_drm_bo(bo);
struct drm_device *drm = obj->gem.dev;
mutex_lock(&drm->struct_mutex);
@@ -99,8 +106,7 @@ static void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo)
dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr);
}
-struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
- unsigned long flags)
+struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size)
{
struct tegra_bo *bo;
int err;
@@ -129,12 +135,6 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
if (err)
goto err_mmap;
- if (flags & DRM_TEGRA_GEM_CREATE_TILED)
- bo->flags |= TEGRA_BO_TILED;
-
- if (flags & DRM_TEGRA_GEM_CREATE_BOTTOM_UP)
- bo->flags |= TEGRA_BO_BOTTOM_UP;
-
return bo;
err_mmap:
@@ -149,15 +149,14 @@ err_dma:
}
struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
- struct drm_device *drm,
- unsigned int size,
- unsigned long flags,
- unsigned int *handle)
+ struct drm_device *drm,
+ unsigned int size,
+ unsigned int *handle)
{
struct tegra_bo *bo;
int ret;
- bo = tegra_bo_create(drm, size, flags);
+ bo = tegra_bo_create(drm, size);
if (IS_ERR(bo))
return bo;
@@ -179,6 +178,7 @@ void tegra_bo_free_object(struct drm_gem_object *gem)
struct tegra_bo *bo = to_tegra_bo(gem);
drm_gem_free_mmap_offset(gem);
+
drm_gem_object_release(gem);
tegra_bo_destroy(gem->dev, bo);
@@ -197,8 +197,8 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
if (args->size < args->pitch * args->height)
args->size = args->pitch * args->height;
- bo = tegra_bo_create_with_handle(file, drm, args->size, 0,
- &args->handle);
+ bo = tegra_bo_create_with_handle(file, drm, args->size,
+ &args->handle);
if (IS_ERR(bo))
return PTR_ERR(bo);
diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/host1x/drm/gem.h
index 7674000..492533a 100644
--- a/drivers/gpu/drm/tegra/gem.h
+++ b/drivers/gpu/host1x/drm/gem.h
@@ -19,18 +19,14 @@
#ifndef __HOST1X_GEM_H
#define __HOST1X_GEM_H
-#include <linux/host1x.h>
-
#include <drm/drm.h>
#include <drm/drmP.h>
-#define TEGRA_BO_TILED (1 << 0)
-#define TEGRA_BO_BOTTOM_UP (1 << 1)
+#include "host1x_bo.h"
struct tegra_bo {
struct drm_gem_object gem;
struct host1x_bo base;
- unsigned long flags;
dma_addr_t paddr;
void *vaddr;
};
@@ -42,13 +38,11 @@ static inline struct tegra_bo *to_tegra_bo(struct drm_gem_object *gem)
extern const struct host1x_bo_ops tegra_bo_ops;
-struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
- unsigned long flags);
+struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size);
struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
- struct drm_device *drm,
- unsigned int size,
- unsigned long flags,
- unsigned int *handle);
+ struct drm_device *drm,
+ unsigned int size,
+ unsigned int *handle);
void tegra_bo_free_object(struct drm_gem_object *gem);
int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
struct drm_mode_create_dumb *args);
diff --git a/drivers/gpu/host1x/drm/gr2d.c b/drivers/gpu/host1x/drm/gr2d.c
new file mode 100644
index 0000000..27ffcf1
--- /dev/null
+++ b/drivers/gpu/host1x/drm/gr2d.c
@@ -0,0 +1,343 @@
+/*
+ * drivers/video/tegra/host/gr2d/gr2d.c
+ *
+ * Tegra Graphics 2D
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk.h>
+
+#include "channel.h"
+#include "drm.h"
+#include "gem.h"
+#include "job.h"
+#include "host1x.h"
+#include "host1x_bo.h"
+#include "host1x_client.h"
+#include "syncpt.h"
+
+struct gr2d {
+ struct host1x_client client;
+ struct clk *clk;
+ struct host1x_channel *channel;
+ unsigned long *addr_regs;
+};
+
+static inline struct gr2d *to_gr2d(struct host1x_client *client)
+{
+ return container_of(client, struct gr2d, client);
+}
+
+static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 reg);
+
+static int gr2d_client_init(struct host1x_client *client,
+ struct drm_device *drm)
+{
+ return 0;
+}
+
+static int gr2d_client_exit(struct host1x_client *client)
+{
+ return 0;
+}
+
+static int gr2d_open_channel(struct host1x_client *client,
+ struct host1x_drm_context *context)
+{
+ struct gr2d *gr2d = to_gr2d(client);
+
+ context->channel = host1x_channel_get(gr2d->channel);
+
+ if (!context->channel)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void gr2d_close_channel(struct host1x_drm_context *context)
+{
+ host1x_channel_put(context->channel);
+}
+
+static struct host1x_bo *host1x_bo_lookup(struct drm_device *drm,
+ struct drm_file *file,
+ u32 handle)
+{
+ struct drm_gem_object *gem;
+ struct tegra_bo *bo;
+
+ gem = drm_gem_object_lookup(drm, file, handle);
+ if (!gem)
+ return NULL;
+
+ mutex_lock(&drm->struct_mutex);
+ drm_gem_object_unreference(gem);
+ mutex_unlock(&drm->struct_mutex);
+
+ bo = to_tegra_bo(gem);
+ return &bo->base;
+}
+
+static int gr2d_submit(struct host1x_drm_context *context,
+ struct drm_tegra_submit *args, struct drm_device *drm,
+ struct drm_file *file)
+{
+ struct host1x_job *job;
+ unsigned int num_cmdbufs = args->num_cmdbufs;
+ unsigned int num_relocs = args->num_relocs;
+ unsigned int num_waitchks = args->num_waitchks;
+ struct drm_tegra_cmdbuf __user *cmdbufs =
+ (void * __user)(uintptr_t)args->cmdbufs;
+ struct drm_tegra_reloc __user *relocs =
+ (void * __user)(uintptr_t)args->relocs;
+ struct drm_tegra_waitchk __user *waitchks =
+ (void * __user)(uintptr_t)args->waitchks;
+ struct drm_tegra_syncpt syncpt;
+ int err;
+
+ /* We don't yet support other than one syncpt_incr struct per submit */
+ if (args->num_syncpts != 1)
+ return -EINVAL;
+
+ job = host1x_job_alloc(context->channel, args->num_cmdbufs,
+ args->num_relocs, args->num_waitchks);
+ if (!job)
+ return -ENOMEM;
+
+ job->num_relocs = args->num_relocs;
+ job->num_waitchk = args->num_waitchks;
+ job->client = (u32)args->context;
+ job->class = context->client->class;
+ job->serialize = true;
+
+ while (num_cmdbufs) {
+ struct drm_tegra_cmdbuf cmdbuf;
+ struct host1x_bo *bo;
+
+ err = copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf));
+ if (err)
+ goto fail;
+
+ bo = host1x_bo_lookup(drm, file, cmdbuf.handle);
+ if (!bo) {
+ err = -ENOENT;
+ goto fail;
+ }
+
+ host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset);
+ num_cmdbufs--;
+ cmdbufs++;
+ }
+
+ err = copy_from_user(job->relocarray, relocs,
+ sizeof(*relocs) * num_relocs);
+ if (err)
+ goto fail;
+
+ while (num_relocs--) {
+ struct host1x_reloc *reloc = &job->relocarray[num_relocs];
+ struct host1x_bo *cmdbuf, *target;
+
+ cmdbuf = host1x_bo_lookup(drm, file, (u32)reloc->cmdbuf);
+ target = host1x_bo_lookup(drm, file, (u32)reloc->target);
+
+ reloc->cmdbuf = cmdbuf;
+ reloc->target = target;
+
+ if (!reloc->target || !reloc->cmdbuf) {
+ err = -ENOENT;
+ goto fail;
+ }
+ }
+
+ err = copy_from_user(job->waitchk, waitchks,
+ sizeof(*waitchks) * num_waitchks);
+ if (err)
+ goto fail;
+
+ err = copy_from_user(&syncpt, (void * __user)(uintptr_t)args->syncpts,
+ sizeof(syncpt));
+ if (err)
+ goto fail;
+
+ job->syncpt_id = syncpt.id;
+ job->syncpt_incrs = syncpt.incrs;
+ job->timeout = 10000;
+ job->is_addr_reg = gr2d_is_addr_reg;
+
+ if (args->timeout && args->timeout < 10000)
+ job->timeout = args->timeout;
+
+ err = host1x_job_pin(job, context->client->dev);
+ if (err)
+ goto fail;
+
+ err = host1x_job_submit(job);
+ if (err)
+ goto fail_submit;
+
+ args->fence = job->syncpt_end;
+
+ host1x_job_put(job);
+ return 0;
+
+fail_submit:
+ host1x_job_unpin(job);
+fail:
+ host1x_job_put(job);
+ return err;
+}
+
+static struct host1x_client_ops gr2d_client_ops = {
+ .drm_init = gr2d_client_init,
+ .drm_exit = gr2d_client_exit,
+ .open_channel = gr2d_open_channel,
+ .close_channel = gr2d_close_channel,
+ .submit = gr2d_submit,
+};
+
+static void gr2d_init_addr_reg_map(struct device *dev, struct gr2d *gr2d)
+{
+ const u32 gr2d_addr_regs[] = {0x1a, 0x1b, 0x26, 0x2b, 0x2c, 0x2d, 0x31,
+ 0x32, 0x48, 0x49, 0x4a, 0x4b, 0x4c};
+ unsigned long *bitmap;
+ int i;
+
+ bitmap = devm_kzalloc(dev, DIV_ROUND_UP(256, BITS_PER_BYTE),
+ GFP_KERNEL);
+
+ for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); ++i) {
+ u32 reg = gr2d_addr_regs[i];
+ bitmap[BIT_WORD(reg)] |= BIT_MASK(reg);
+ }
+
+ gr2d->addr_regs = bitmap;
+}
+
+static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 reg)
+{
+ struct gr2d *gr2d = dev_get_drvdata(dev);
+
+ switch (class) {
+ case HOST1X_CLASS_HOST1X:
+ return reg == 0x2b;
+ case HOST1X_CLASS_GR2D:
+ case HOST1X_CLASS_GR2D_SB:
+ reg &= 0xff;
+ if (gr2d->addr_regs[BIT_WORD(reg)] & BIT_MASK(reg))
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static const struct of_device_id gr2d_match[] = {
+ { .compatible = "nvidia,tegra30-gr2d" },
+ { .compatible = "nvidia,tegra20-gr2d" },
+ { },
+};
+
+static int gr2d_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct host1x_drm *host1x = host1x_get_drm_data(dev->parent);
+ int err;
+ struct gr2d *gr2d = NULL;
+ struct host1x_syncpt **syncpts;
+
+ gr2d = devm_kzalloc(dev, sizeof(*gr2d), GFP_KERNEL);
+ if (!gr2d)
+ return -ENOMEM;
+
+ syncpts = devm_kzalloc(dev, sizeof(*syncpts), GFP_KERNEL);
+ if (!syncpts)
+ return -ENOMEM;
+
+ gr2d->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(gr2d->clk)) {
+ dev_err(dev, "cannot get clock\n");
+ return PTR_ERR(gr2d->clk);
+ }
+
+ err = clk_prepare_enable(gr2d->clk);
+ if (err) {
+ dev_err(dev, "cannot turn on clock\n");
+ return err;
+ }
+
+ gr2d->channel = host1x_channel_request(dev);
+ if (!gr2d->channel)
+ return -ENOMEM;
+
+ *syncpts = host1x_syncpt_request(dev, false);
+ if (!(*syncpts)) {
+ host1x_channel_free(gr2d->channel);
+ return -ENOMEM;
+ }
+
+ gr2d->client.ops = &gr2d_client_ops;
+ gr2d->client.dev = dev;
+ gr2d->client.class = HOST1X_CLASS_GR2D;
+ gr2d->client.syncpts = syncpts;
+ gr2d->client.num_syncpts = 1;
+
+ err = host1x_register_client(host1x, &gr2d->client);
+ if (err < 0) {
+ dev_err(dev, "failed to register host1x client: %d\n", err);
+ return err;
+ }
+
+ gr2d_init_addr_reg_map(dev, gr2d);
+
+ platform_set_drvdata(pdev, gr2d);
+
+ return 0;
+}
+
+static int __exit gr2d_remove(struct platform_device *pdev)
+{
+ struct host1x_drm *host1x = host1x_get_drm_data(pdev->dev.parent);
+ struct gr2d *gr2d = platform_get_drvdata(pdev);
+ unsigned int i;
+ int err;
+
+ err = host1x_unregister_client(host1x, &gr2d->client);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to unregister client: %d\n", err);
+ return err;
+ }
+
+ for (i = 0; i < gr2d->client.num_syncpts; i++)
+ host1x_syncpt_free(gr2d->client.syncpts[i]);
+
+ host1x_channel_free(gr2d->channel);
+ clk_disable_unprepare(gr2d->clk);
+
+ return 0;
+}
+
+struct platform_driver tegra_gr2d_driver = {
+ .probe = gr2d_probe,
+ .remove = __exit_p(gr2d_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "gr2d",
+ .of_match_table = gr2d_match,
+ }
+};
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index 0cd9bc2..644d95c 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -8,33 +8,21 @@
*/
#include <linux/clk.h>
-#include <linux/clk/tegra.h>
#include <linux/debugfs.h>
+#include <linux/gpio.h>
#include <linux/hdmi.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/clk/tegra.h>
+
+#include <drm/drm_edid.h>
#include "hdmi.h"
#include "drm.h"
#include "dc.h"
-
-struct tmds_config {
- unsigned int pclk;
- u32 pll0;
- u32 pll1;
- u32 pe_current;
- u32 drive_current;
- u32 peak_current;
-};
-
-struct tegra_hdmi_config {
- const struct tmds_config *tmds;
- unsigned int num_tmds;
-
- unsigned long fuse_override_offset;
- unsigned long fuse_override_value;
-
- bool has_sor_io_peak_current;
-};
+#include "host1x_client.h"
struct tegra_hdmi {
struct host1x_client client;
@@ -50,8 +38,6 @@ struct tegra_hdmi {
struct clk *clk_parent;
struct clk *clk;
- const struct tegra_hdmi_config *config;
-
unsigned int audio_source;
unsigned int audio_freq;
bool stereo;
@@ -157,7 +143,15 @@ static const struct tegra_hdmi_audio_config tegra_hdmi_audio_192k[] = {
{ 0, 0, 0, 0 },
};
-static const struct tmds_config tegra20_tmds_config[] = {
+struct tmds_config {
+ unsigned int pclk;
+ u32 pll0;
+ u32 pll1;
+ u32 pe_current;
+ u32 drive_current;
+};
+
+static const struct tmds_config tegra2_tmds_config[] = {
{ /* slow pixel clock modes */
.pclk = 27000000,
.pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
@@ -190,7 +184,7 @@ static const struct tmds_config tegra20_tmds_config[] = {
},
};
-static const struct tmds_config tegra30_tmds_config[] = {
+static const struct tmds_config tegra3_tmds_config[] = {
{ /* 480p modes */
.pclk = 27000000,
.pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
@@ -236,85 +230,6 @@ static const struct tmds_config tegra30_tmds_config[] = {
},
};
-static const struct tmds_config tegra114_tmds_config[] = {
- { /* 480p/576p / 25.2MHz/27MHz modes */
- .pclk = 27000000,
- .pll0 = SOR_PLL_ICHPMP(1) | SOR_PLL_BG_V17_S(3) |
- SOR_PLL_VCOCAP(0) | SOR_PLL_RESISTORSEL,
- .pll1 = SOR_PLL_LOADADJ(3) | SOR_PLL_TMDS_TERMADJ(0),
- .pe_current = PE_CURRENT0(PE_CURRENT_0_mA_T114) |
- PE_CURRENT1(PE_CURRENT_0_mA_T114) |
- PE_CURRENT2(PE_CURRENT_0_mA_T114) |
- PE_CURRENT3(PE_CURRENT_0_mA_T114),
- .drive_current =
- DRIVE_CURRENT_LANE0_T114(DRIVE_CURRENT_10_400_mA_T114) |
- DRIVE_CURRENT_LANE1_T114(DRIVE_CURRENT_10_400_mA_T114) |
- DRIVE_CURRENT_LANE2_T114(DRIVE_CURRENT_10_400_mA_T114) |
- DRIVE_CURRENT_LANE3_T114(DRIVE_CURRENT_10_400_mA_T114),
- .peak_current = PEAK_CURRENT_LANE0(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE1(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE2(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE3(PEAK_CURRENT_0_000_mA),
- }, { /* 720p / 74.25MHz modes */
- .pclk = 74250000,
- .pll0 = SOR_PLL_ICHPMP(1) | SOR_PLL_BG_V17_S(3) |
- SOR_PLL_VCOCAP(1) | SOR_PLL_RESISTORSEL,
- .pll1 = SOR_PLL_PE_EN | SOR_PLL_LOADADJ(3) |
- SOR_PLL_TMDS_TERMADJ(0),
- .pe_current = PE_CURRENT0(PE_CURRENT_15_mA_T114) |
- PE_CURRENT1(PE_CURRENT_15_mA_T114) |
- PE_CURRENT2(PE_CURRENT_15_mA_T114) |
- PE_CURRENT3(PE_CURRENT_15_mA_T114),
- .drive_current =
- DRIVE_CURRENT_LANE0_T114(DRIVE_CURRENT_10_400_mA_T114) |
- DRIVE_CURRENT_LANE1_T114(DRIVE_CURRENT_10_400_mA_T114) |
- DRIVE_CURRENT_LANE2_T114(DRIVE_CURRENT_10_400_mA_T114) |
- DRIVE_CURRENT_LANE3_T114(DRIVE_CURRENT_10_400_mA_T114),
- .peak_current = PEAK_CURRENT_LANE0(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE1(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE2(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE3(PEAK_CURRENT_0_000_mA),
- }, { /* 1080p / 148.5MHz modes */
- .pclk = 148500000,
- .pll0 = SOR_PLL_ICHPMP(1) | SOR_PLL_BG_V17_S(3) |
- SOR_PLL_VCOCAP(3) | SOR_PLL_RESISTORSEL,
- .pll1 = SOR_PLL_PE_EN | SOR_PLL_LOADADJ(3) |
- SOR_PLL_TMDS_TERMADJ(0),
- .pe_current = PE_CURRENT0(PE_CURRENT_10_mA_T114) |
- PE_CURRENT1(PE_CURRENT_10_mA_T114) |
- PE_CURRENT2(PE_CURRENT_10_mA_T114) |
- PE_CURRENT3(PE_CURRENT_10_mA_T114),
- .drive_current =
- DRIVE_CURRENT_LANE0_T114(DRIVE_CURRENT_12_400_mA_T114) |
- DRIVE_CURRENT_LANE1_T114(DRIVE_CURRENT_12_400_mA_T114) |
- DRIVE_CURRENT_LANE2_T114(DRIVE_CURRENT_12_400_mA_T114) |
- DRIVE_CURRENT_LANE3_T114(DRIVE_CURRENT_12_400_mA_T114),
- .peak_current = PEAK_CURRENT_LANE0(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE1(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE2(PEAK_CURRENT_0_000_mA) |
- PEAK_CURRENT_LANE3(PEAK_CURRENT_0_000_mA),
- }, { /* 225/297MHz modes */
- .pclk = UINT_MAX,
- .pll0 = SOR_PLL_ICHPMP(1) | SOR_PLL_BG_V17_S(3) |
- SOR_PLL_VCOCAP(0xf) | SOR_PLL_RESISTORSEL,
- .pll1 = SOR_PLL_LOADADJ(3) | SOR_PLL_TMDS_TERMADJ(7)
- | SOR_PLL_TMDS_TERM_ENABLE,
- .pe_current = PE_CURRENT0(PE_CURRENT_0_mA_T114) |
- PE_CURRENT1(PE_CURRENT_0_mA_T114) |
- PE_CURRENT2(PE_CURRENT_0_mA_T114) |
- PE_CURRENT3(PE_CURRENT_0_mA_T114),
- .drive_current =
- DRIVE_CURRENT_LANE0_T114(DRIVE_CURRENT_25_200_mA_T114) |
- DRIVE_CURRENT_LANE1_T114(DRIVE_CURRENT_25_200_mA_T114) |
- DRIVE_CURRENT_LANE2_T114(DRIVE_CURRENT_25_200_mA_T114) |
- DRIVE_CURRENT_LANE3_T114(DRIVE_CURRENT_19_200_mA_T114),
- .peak_current = PEAK_CURRENT_LANE0(PEAK_CURRENT_3_000_mA) |
- PEAK_CURRENT_LANE1(PEAK_CURRENT_3_000_mA) |
- PEAK_CURRENT_LANE2(PEAK_CURRENT_3_000_mA) |
- PEAK_CURRENT_LANE3(PEAK_CURRENT_0_800_mA),
- },
-};
-
static const struct tegra_hdmi_audio_config *
tegra_hdmi_get_audio_config(unsigned int audio_freq, unsigned int pclk)
{
@@ -596,7 +511,7 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
err = hdmi_audio_infoframe_init(&frame);
if (err < 0) {
- dev_err(hdmi->dev, "failed to setup audio infoframe: %zd\n",
+ dev_err(hdmi->dev, "failed to initialize audio infoframe: %d\n",
err);
return;
}
@@ -616,7 +531,7 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
* contain 7 bytes. Including the 3 byte header only the first 10
* bytes can be programmed.
*/
- tegra_hdmi_write_infopack(hdmi, buffer, min_t(size_t, 10, err));
+ tegra_hdmi_write_infopack(hdmi, buffer, min(10, err));
tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
@@ -662,28 +577,8 @@ static void tegra_hdmi_setup_tmds(struct tegra_hdmi *hdmi,
tegra_hdmi_writel(hdmi, tmds->pll1, HDMI_NV_PDISP_SOR_PLL1);
tegra_hdmi_writel(hdmi, tmds->pe_current, HDMI_NV_PDISP_PE_CURRENT);
- tegra_hdmi_writel(hdmi, tmds->drive_current,
- HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
-
- value = tegra_hdmi_readl(hdmi, hdmi->config->fuse_override_offset);
- value |= hdmi->config->fuse_override_value;
- tegra_hdmi_writel(hdmi, value, hdmi->config->fuse_override_offset);
-
- if (hdmi->config->has_sor_io_peak_current)
- tegra_hdmi_writel(hdmi, tmds->peak_current,
- HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT);
-}
-
-static bool tegra_output_is_hdmi(struct tegra_output *output)
-{
- struct edid *edid;
-
- if (!output->connector.edid_blob_ptr)
- return false;
-
- edid = (struct edid *)output->connector.edid_blob_ptr->data;
-
- return drm_detect_hdmi_monitor(edid);
+ value = tmds->drive_current | DRIVE_CURRENT_FUSE_OVERRIDE;
+ tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
}
static int tegra_output_hdmi_enable(struct tegra_output *output)
@@ -694,17 +589,23 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
struct tegra_hdmi *hdmi = to_hdmi(output);
struct device_node *node = hdmi->dev->of_node;
unsigned int pulse_start, div82, pclk;
+ const struct tmds_config *tmds;
+ unsigned int num_tmds;
unsigned long value;
int retries = 1000;
int err;
- hdmi->dvi = !tegra_output_is_hdmi(output);
-
pclk = mode->clock * 1000;
h_sync_width = mode->hsync_end - mode->hsync_start;
h_back_porch = mode->htotal - mode->hsync_end;
h_front_porch = mode->hsync_start - mode->hdisplay;
+ err = regulator_enable(hdmi->vdd);
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to enable VDD regulator: %d\n", err);
+ return err;
+ }
+
err = regulator_enable(hdmi->pll);
if (err < 0) {
dev_err(hdmi->dev, "failed to enable PLL regulator: %d\n", err);
@@ -809,9 +710,17 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
tegra_hdmi_setup_stereo_infoframe(hdmi);
/* TMDS CONFIG */
- for (i = 0; i < hdmi->config->num_tmds; i++) {
- if (pclk <= hdmi->config->tmds[i].pclk) {
- tegra_hdmi_setup_tmds(hdmi, &hdmi->config->tmds[i]);
+ if (of_device_is_compatible(node, "nvidia,tegra30-hdmi")) {
+ num_tmds = ARRAY_SIZE(tegra3_tmds_config);
+ tmds = tegra3_tmds_config;
+ } else {
+ num_tmds = ARRAY_SIZE(tegra2_tmds_config);
+ tmds = tegra2_tmds_config;
+ }
+
+ for (i = 0; i < num_tmds; i++) {
+ if (pclk <= tmds[i].pclk) {
+ tegra_hdmi_setup_tmds(hdmi, &tmds[i]);
break;
}
}
@@ -915,6 +824,7 @@ static int tegra_output_hdmi_disable(struct tegra_output *output)
tegra_periph_reset_assert(hdmi->clk);
clk_disable(hdmi->clk);
regulator_disable(hdmi->pll);
+ regulator_disable(hdmi->vdd);
return 0;
}
@@ -1145,7 +1055,6 @@ static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0);
DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR);
DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE);
- DUMP_REG(HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT);
#undef DUMP_REG
@@ -1213,31 +1122,24 @@ static int tegra_hdmi_debugfs_exit(struct tegra_hdmi *hdmi)
return 0;
}
-static int tegra_hdmi_init(struct host1x_client *client)
+static int tegra_hdmi_drm_init(struct host1x_client *client,
+ struct drm_device *drm)
{
- struct tegra_drm *tegra = dev_get_drvdata(client->parent);
struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
int err;
- err = regulator_enable(hdmi->vdd);
- if (err < 0) {
- dev_err(client->dev, "failed to enable VDD regulator: %d\n",
- err);
- return err;
- }
-
hdmi->output.type = TEGRA_OUTPUT_HDMI;
hdmi->output.dev = client->dev;
hdmi->output.ops = &hdmi_ops;
- err = tegra_output_init(tegra->drm, &hdmi->output);
+ err = tegra_output_init(drm, &hdmi->output);
if (err < 0) {
dev_err(client->dev, "output setup failed: %d\n", err);
return err;
}
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
- err = tegra_hdmi_debugfs_init(hdmi, tegra->drm->primary);
+ err = tegra_hdmi_debugfs_init(hdmi, drm->primary);
if (err < 0)
dev_err(client->dev, "debugfs setup failed: %d\n", err);
}
@@ -1245,7 +1147,7 @@ static int tegra_hdmi_init(struct host1x_client *client)
return 0;
}
-static int tegra_hdmi_exit(struct host1x_client *client)
+static int tegra_hdmi_drm_exit(struct host1x_client *client)
{
struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
int err;
@@ -1269,63 +1171,25 @@ static int tegra_hdmi_exit(struct host1x_client *client)
return err;
}
- regulator_disable(hdmi->vdd);
-
return 0;
}
static const struct host1x_client_ops hdmi_client_ops = {
- .init = tegra_hdmi_init,
- .exit = tegra_hdmi_exit,
-};
-
-static const struct tegra_hdmi_config tegra20_hdmi_config = {
- .tmds = tegra20_tmds_config,
- .num_tmds = ARRAY_SIZE(tegra20_tmds_config),
- .fuse_override_offset = HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT,
- .fuse_override_value = 1 << 31,
- .has_sor_io_peak_current = false,
-};
-
-static const struct tegra_hdmi_config tegra30_hdmi_config = {
- .tmds = tegra30_tmds_config,
- .num_tmds = ARRAY_SIZE(tegra30_tmds_config),
- .fuse_override_offset = HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT,
- .fuse_override_value = 1 << 31,
- .has_sor_io_peak_current = false,
-};
-
-static const struct tegra_hdmi_config tegra114_hdmi_config = {
- .tmds = tegra114_tmds_config,
- .num_tmds = ARRAY_SIZE(tegra114_tmds_config),
- .fuse_override_offset = HDMI_NV_PDISP_SOR_PAD_CTLS0,
- .fuse_override_value = 1 << 31,
- .has_sor_io_peak_current = true,
-};
-
-static const struct of_device_id tegra_hdmi_of_match[] = {
- { .compatible = "nvidia,tegra114-hdmi", .data = &tegra114_hdmi_config },
- { .compatible = "nvidia,tegra30-hdmi", .data = &tegra30_hdmi_config },
- { .compatible = "nvidia,tegra20-hdmi", .data = &tegra20_hdmi_config },
- { },
+ .drm_init = tegra_hdmi_drm_init,
+ .drm_exit = tegra_hdmi_drm_exit,
};
static int tegra_hdmi_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
+ struct host1x_drm *host1x = host1x_get_drm_data(pdev->dev.parent);
struct tegra_hdmi *hdmi;
struct resource *regs;
int err;
- match = of_match_node(tegra_hdmi_of_match, pdev->dev.of_node);
- if (!match)
- return -ENODEV;
-
hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
- hdmi->config = match->data;
hdmi->dev = &pdev->dev;
hdmi->audio_source = AUTO;
hdmi->audio_freq = 44100;
@@ -1370,7 +1234,7 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
hdmi->output.dev = &pdev->dev;
- err = tegra_output_probe(&hdmi->output);
+ err = tegra_output_parse_dt(&hdmi->output);
if (err < 0)
return err;
@@ -1388,11 +1252,11 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
hdmi->irq = err;
- INIT_LIST_HEAD(&hdmi->client.list);
hdmi->client.ops = &hdmi_client_ops;
+ INIT_LIST_HEAD(&hdmi->client.list);
hdmi->client.dev = &pdev->dev;
- err = host1x_client_register(&hdmi->client);
+ err = host1x_register_client(host1x, &hdmi->client);
if (err < 0) {
dev_err(&pdev->dev, "failed to register host1x client: %d\n",
err);
@@ -1406,28 +1270,29 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
static int tegra_hdmi_remove(struct platform_device *pdev)
{
+ struct host1x_drm *host1x = host1x_get_drm_data(pdev->dev.parent);
struct tegra_hdmi *hdmi = platform_get_drvdata(pdev);
int err;
- err = host1x_client_unregister(&hdmi->client);
+ err = host1x_unregister_client(host1x, &hdmi->client);
if (err < 0) {
dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
err);
return err;
}
- err = tegra_output_remove(&hdmi->output);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to remove output: %d\n", err);
- return err;
- }
-
clk_unprepare(hdmi->clk_parent);
clk_unprepare(hdmi->clk);
return 0;
}
+static struct of_device_id tegra_hdmi_of_match[] = {
+ { .compatible = "nvidia,tegra30-hdmi", },
+ { .compatible = "nvidia,tegra20-hdmi", },
+ { },
+};
+
struct platform_driver tegra_hdmi_driver = {
.driver = {
.name = "tegra-hdmi",
diff --git a/drivers/gpu/drm/tegra/hdmi.h b/drivers/gpu/host1x/drm/hdmi.h
index 0aebc48..52ac36e 100644
--- a/drivers/gpu/drm/tegra/hdmi.h
+++ b/drivers/gpu/host1x/drm/hdmi.h
@@ -233,10 +233,7 @@
#define DRIVE_CURRENT_LANE1(x) (((x) & 0x3f) << 8)
#define DRIVE_CURRENT_LANE2(x) (((x) & 0x3f) << 16)
#define DRIVE_CURRENT_LANE3(x) (((x) & 0x3f) << 24)
-#define DRIVE_CURRENT_LANE0_T114(x) (((x) & 0x7f) << 0)
-#define DRIVE_CURRENT_LANE1_T114(x) (((x) & 0x7f) << 8)
-#define DRIVE_CURRENT_LANE2_T114(x) (((x) & 0x7f) << 16)
-#define DRIVE_CURRENT_LANE3_T114(x) (((x) & 0x7f) << 24)
+#define DRIVE_CURRENT_FUSE_OVERRIDE (1 << 31)
#define DRIVE_CURRENT_1_500_mA 0x00
#define DRIVE_CURRENT_1_875_mA 0x01
@@ -302,79 +299,6 @@
#define DRIVE_CURRENT_24_375_mA 0x3d
#define DRIVE_CURRENT_24_750_mA 0x3e
-#define DRIVE_CURRENT_0_000_mA_T114 0x00
-#define DRIVE_CURRENT_0_400_mA_T114 0x01
-#define DRIVE_CURRENT_0_800_mA_T114 0x02
-#define DRIVE_CURRENT_1_200_mA_T114 0x03
-#define DRIVE_CURRENT_1_600_mA_T114 0x04
-#define DRIVE_CURRENT_2_000_mA_T114 0x05
-#define DRIVE_CURRENT_2_400_mA_T114 0x06
-#define DRIVE_CURRENT_2_800_mA_T114 0x07
-#define DRIVE_CURRENT_3_200_mA_T114 0x08
-#define DRIVE_CURRENT_3_600_mA_T114 0x09
-#define DRIVE_CURRENT_4_000_mA_T114 0x0a
-#define DRIVE_CURRENT_4_400_mA_T114 0x0b
-#define DRIVE_CURRENT_4_800_mA_T114 0x0c
-#define DRIVE_CURRENT_5_200_mA_T114 0x0d
-#define DRIVE_CURRENT_5_600_mA_T114 0x0e
-#define DRIVE_CURRENT_6_000_mA_T114 0x0f
-#define DRIVE_CURRENT_6_400_mA_T114 0x10
-#define DRIVE_CURRENT_6_800_mA_T114 0x11
-#define DRIVE_CURRENT_7_200_mA_T114 0x12
-#define DRIVE_CURRENT_7_600_mA_T114 0x13
-#define DRIVE_CURRENT_8_000_mA_T114 0x14
-#define DRIVE_CURRENT_8_400_mA_T114 0x15
-#define DRIVE_CURRENT_8_800_mA_T114 0x16
-#define DRIVE_CURRENT_9_200_mA_T114 0x17
-#define DRIVE_CURRENT_9_600_mA_T114 0x18
-#define DRIVE_CURRENT_10_000_mA_T114 0x19
-#define DRIVE_CURRENT_10_400_mA_T114 0x1a
-#define DRIVE_CURRENT_10_800_mA_T114 0x1b
-#define DRIVE_CURRENT_11_200_mA_T114 0x1c
-#define DRIVE_CURRENT_11_600_mA_T114 0x1d
-#define DRIVE_CURRENT_12_000_mA_T114 0x1e
-#define DRIVE_CURRENT_12_400_mA_T114 0x1f
-#define DRIVE_CURRENT_12_800_mA_T114 0x20
-#define DRIVE_CURRENT_13_200_mA_T114 0x21
-#define DRIVE_CURRENT_13_600_mA_T114 0x22
-#define DRIVE_CURRENT_14_000_mA_T114 0x23
-#define DRIVE_CURRENT_14_400_mA_T114 0x24
-#define DRIVE_CURRENT_14_800_mA_T114 0x25
-#define DRIVE_CURRENT_15_200_mA_T114 0x26
-#define DRIVE_CURRENT_15_600_mA_T114 0x27
-#define DRIVE_CURRENT_16_000_mA_T114 0x28
-#define DRIVE_CURRENT_16_400_mA_T114 0x29
-#define DRIVE_CURRENT_16_800_mA_T114 0x2a
-#define DRIVE_CURRENT_17_200_mA_T114 0x2b
-#define DRIVE_CURRENT_17_600_mA_T114 0x2c
-#define DRIVE_CURRENT_18_000_mA_T114 0x2d
-#define DRIVE_CURRENT_18_400_mA_T114 0x2e
-#define DRIVE_CURRENT_18_800_mA_T114 0x2f
-#define DRIVE_CURRENT_19_200_mA_T114 0x30
-#define DRIVE_CURRENT_19_600_mA_T114 0x31
-#define DRIVE_CURRENT_20_000_mA_T114 0x32
-#define DRIVE_CURRENT_20_400_mA_T114 0x33
-#define DRIVE_CURRENT_20_800_mA_T114 0x34
-#define DRIVE_CURRENT_21_200_mA_T114 0x35
-#define DRIVE_CURRENT_21_600_mA_T114 0x36
-#define DRIVE_CURRENT_22_000_mA_T114 0x37
-#define DRIVE_CURRENT_22_400_mA_T114 0x38
-#define DRIVE_CURRENT_22_800_mA_T114 0x39
-#define DRIVE_CURRENT_23_200_mA_T114 0x3a
-#define DRIVE_CURRENT_23_600_mA_T114 0x3b
-#define DRIVE_CURRENT_24_000_mA_T114 0x3c
-#define DRIVE_CURRENT_24_400_mA_T114 0x3d
-#define DRIVE_CURRENT_24_800_mA_T114 0x3e
-#define DRIVE_CURRENT_25_200_mA_T114 0x3f
-#define DRIVE_CURRENT_25_400_mA_T114 0x40
-#define DRIVE_CURRENT_25_800_mA_T114 0x41
-#define DRIVE_CURRENT_26_200_mA_T114 0x42
-#define DRIVE_CURRENT_26_600_mA_T114 0x43
-#define DRIVE_CURRENT_27_000_mA_T114 0x44
-#define DRIVE_CURRENT_27_400_mA_T114 0x45
-#define DRIVE_CURRENT_27_800_mA_T114 0x46
-#define DRIVE_CURRENT_28_200_mA_T114 0x47
-
#define HDMI_NV_PDISP_AUDIO_DEBUG0 0x7f
#define HDMI_NV_PDISP_AUDIO_DEBUG1 0x80
#define HDMI_NV_PDISP_AUDIO_DEBUG2 0x81
@@ -434,23 +358,6 @@
#define PE_CURRENT_7_0_mA 0xe
#define PE_CURRENT_7_5_mA 0xf
-#define PE_CURRENT_0_mA_T114 0x0
-#define PE_CURRENT_1_mA_T114 0x1
-#define PE_CURRENT_2_mA_T114 0x2
-#define PE_CURRENT_3_mA_T114 0x3
-#define PE_CURRENT_4_mA_T114 0x4
-#define PE_CURRENT_5_mA_T114 0x5
-#define PE_CURRENT_6_mA_T114 0x6
-#define PE_CURRENT_7_mA_T114 0x7
-#define PE_CURRENT_8_mA_T114 0x8
-#define PE_CURRENT_9_mA_T114 0x9
-#define PE_CURRENT_10_mA_T114 0xa
-#define PE_CURRENT_11_mA_T114 0xb
-#define PE_CURRENT_12_mA_T114 0xc
-#define PE_CURRENT_13_mA_T114 0xd
-#define PE_CURRENT_14_mA_T114 0xe
-#define PE_CURRENT_15_mA_T114 0xf
-
#define HDMI_NV_PDISP_KEY_CTRL 0x9a
#define HDMI_NV_PDISP_KEY_DEBUG0 0x9b
#define HDMI_NV_PDISP_KEY_DEBUG1 0x9c
@@ -476,61 +383,4 @@
#define HDMI_NV_PDISP_SOR_AUDIO_AVAL_1920 0xc5
#define HDMI_NV_PDISP_SOR_AUDIO_AVAL_DEFAULT 0xc5
-#define HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT 0xd1
-#define PEAK_CURRENT_LANE0(x) (((x) & 0x7f) << 0)
-#define PEAK_CURRENT_LANE1(x) (((x) & 0x7f) << 8)
-#define PEAK_CURRENT_LANE2(x) (((x) & 0x7f) << 16)
-#define PEAK_CURRENT_LANE3(x) (((x) & 0x7f) << 24)
-
-#define PEAK_CURRENT_0_000_mA 0x00
-#define PEAK_CURRENT_0_200_mA 0x01
-#define PEAK_CURRENT_0_400_mA 0x02
-#define PEAK_CURRENT_0_600_mA 0x03
-#define PEAK_CURRENT_0_800_mA 0x04
-#define PEAK_CURRENT_1_000_mA 0x05
-#define PEAK_CURRENT_1_200_mA 0x06
-#define PEAK_CURRENT_1_400_mA 0x07
-#define PEAK_CURRENT_1_600_mA 0x08
-#define PEAK_CURRENT_1_800_mA 0x09
-#define PEAK_CURRENT_2_000_mA 0x0a
-#define PEAK_CURRENT_2_200_mA 0x0b
-#define PEAK_CURRENT_2_400_mA 0x0c
-#define PEAK_CURRENT_2_600_mA 0x0d
-#define PEAK_CURRENT_2_800_mA 0x0e
-#define PEAK_CURRENT_3_000_mA 0x0f
-#define PEAK_CURRENT_3_200_mA 0x10
-#define PEAK_CURRENT_3_400_mA 0x11
-#define PEAK_CURRENT_3_600_mA 0x12
-#define PEAK_CURRENT_3_800_mA 0x13
-#define PEAK_CURRENT_4_000_mA 0x14
-#define PEAK_CURRENT_4_200_mA 0x15
-#define PEAK_CURRENT_4_400_mA 0x16
-#define PEAK_CURRENT_4_600_mA 0x17
-#define PEAK_CURRENT_4_800_mA 0x18
-#define PEAK_CURRENT_5_000_mA 0x19
-#define PEAK_CURRENT_5_200_mA 0x1a
-#define PEAK_CURRENT_5_400_mA 0x1b
-#define PEAK_CURRENT_5_600_mA 0x1c
-#define PEAK_CURRENT_5_800_mA 0x1d
-#define PEAK_CURRENT_6_000_mA 0x1e
-#define PEAK_CURRENT_6_200_mA 0x1f
-#define PEAK_CURRENT_6_400_mA 0x20
-#define PEAK_CURRENT_6_600_mA 0x21
-#define PEAK_CURRENT_6_800_mA 0x22
-#define PEAK_CURRENT_7_000_mA 0x23
-#define PEAK_CURRENT_7_200_mA 0x24
-#define PEAK_CURRENT_7_400_mA 0x25
-#define PEAK_CURRENT_7_600_mA 0x26
-#define PEAK_CURRENT_7_800_mA 0x27
-#define PEAK_CURRENT_8_000_mA 0x28
-#define PEAK_CURRENT_8_200_mA 0x29
-#define PEAK_CURRENT_8_400_mA 0x2a
-#define PEAK_CURRENT_8_600_mA 0x2b
-#define PEAK_CURRENT_8_800_mA 0x2c
-#define PEAK_CURRENT_9_000_mA 0x2d
-#define PEAK_CURRENT_9_200_mA 0x2e
-#define PEAK_CURRENT_9_400_mA 0x2f
-
-#define HDMI_NV_PDISP_SOR_PAD_CTLS0 0xd2
-
#endif /* TEGRA_HDMI_H */
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/host1x/drm/output.c
index 2cb0065..137ae81 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/host1x/drm/output.c
@@ -7,7 +7,9 @@
* published by the Free Software Foundation.
*/
+#include <linux/module.h>
#include <linux/of_gpio.h>
+#include <linux/i2c.h>
#include "drm.h"
@@ -79,16 +81,10 @@ tegra_connector_detect(struct drm_connector *connector, bool force)
return status;
}
-static void drm_connector_clear(struct drm_connector *connector)
-{
- memset(connector, 0, sizeof(*connector));
-}
-
static void tegra_connector_destroy(struct drm_connector *connector)
{
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
- drm_connector_clear(connector);
}
static const struct drm_connector_funcs connector_funcs = {
@@ -98,15 +94,9 @@ static const struct drm_connector_funcs connector_funcs = {
.destroy = tegra_connector_destroy,
};
-static void drm_encoder_clear(struct drm_encoder *encoder)
-{
- memset(encoder, 0, sizeof(*encoder));
-}
-
static void tegra_encoder_destroy(struct drm_encoder *encoder)
{
drm_encoder_cleanup(encoder);
- drm_encoder_clear(encoder);
}
static const struct drm_encoder_funcs encoder_funcs = {
@@ -161,7 +151,7 @@ static irqreturn_t hpd_irq(int irq, void *data)
return IRQ_HANDLED;
}
-int tegra_output_probe(struct tegra_output *output)
+int tegra_output_parse_dt(struct tegra_output *output)
{
enum of_gpio_flags flags;
struct device_node *ddc;
@@ -191,6 +181,14 @@ int tegra_output_probe(struct tegra_output *output)
output->hpd_gpio = of_get_named_gpio_flags(output->of_node,
"nvidia,hpd-gpio", 0,
&flags);
+
+ return 0;
+}
+
+int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
+{
+ int connector, encoder, err;
+
if (gpio_is_valid(output->hpd_gpio)) {
unsigned long flags;
@@ -204,8 +202,7 @@ int tegra_output_probe(struct tegra_output *output)
err = gpio_to_irq(output->hpd_gpio);
if (err < 0) {
dev_err(output->dev, "gpio_to_irq(): %d\n", err);
- gpio_free(output->hpd_gpio);
- return err;
+ goto free_hpd;
}
output->hpd_irq = err;
@@ -218,33 +215,12 @@ int tegra_output_probe(struct tegra_output *output)
if (err < 0) {
dev_err(output->dev, "failed to request IRQ#%u: %d\n",
output->hpd_irq, err);
- gpio_free(output->hpd_gpio);
- return err;
+ goto free_hpd;
}
output->connector.polled = DRM_CONNECTOR_POLL_HPD;
}
- return 0;
-}
-
-int tegra_output_remove(struct tegra_output *output)
-{
- if (gpio_is_valid(output->hpd_gpio)) {
- free_irq(output->hpd_irq, output);
- gpio_free(output->hpd_gpio);
- }
-
- if (output->ddc)
- put_device(&output->ddc->dev);
-
- return 0;
-}
-
-int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
-{
- int connector, encoder;
-
switch (output->type) {
case TEGRA_OUTPUT_RGB:
connector = DRM_MODE_CONNECTOR_LVDS;
@@ -265,7 +241,6 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
drm_connector_init(drm, &output->connector, &connector_funcs,
connector);
drm_connector_helper_add(&output->connector, &connector_helper_funcs);
- output->connector.dpms = DRM_MODE_DPMS_OFF;
drm_encoder_init(drm, &output->encoder, &encoder_funcs, encoder);
drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs);
@@ -276,9 +251,22 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
output->encoder.possible_crtcs = 0x3;
return 0;
+
+free_hpd:
+ gpio_free(output->hpd_gpio);
+
+ return err;
}
int tegra_output_exit(struct tegra_output *output)
{
+ if (gpio_is_valid(output->hpd_gpio)) {
+ free_irq(output->hpd_irq, output);
+ gpio_free(output->hpd_gpio);
+ }
+
+ if (output->ddc)
+ put_device(&output->ddc->dev);
+
return 0;
}
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/host1x/drm/rgb.c
index 3b29018..5aa66ef 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/host1x/drm/rgb.c
@@ -8,14 +8,15 @@
*/
#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include "drm.h"
#include "dc.h"
struct tegra_rgb {
struct tegra_output output;
- struct tegra_dc *dc;
-
struct clk *clk_parent;
struct clk *clk;
};
@@ -86,18 +87,18 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
static int tegra_output_rgb_enable(struct tegra_output *output)
{
- struct tegra_rgb *rgb = to_rgb(output);
+ struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
- tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));
+ tegra_dc_write_regs(dc, rgb_enable, ARRAY_SIZE(rgb_enable));
return 0;
}
static int tegra_output_rgb_disable(struct tegra_output *output)
{
- struct tegra_rgb *rgb = to_rgb(output);
+ struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
- tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable));
+ tegra_dc_write_regs(dc, rgb_disable, ARRAY_SIZE(rgb_disable));
return 0;
}
@@ -148,9 +149,8 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
rgb->output.dev = dc->dev;
rgb->output.of_node = np;
- rgb->dc = dc;
- err = tegra_output_probe(&rgb->output);
+ err = tegra_output_parse_dt(&rgb->output);
if (err < 0)
return err;
@@ -177,20 +177,6 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
return 0;
}
-int tegra_dc_rgb_remove(struct tegra_dc *dc)
-{
- int err;
-
- if (!dc->rgb)
- return 0;
-
- err = tegra_output_remove(dc->rgb);
- if (err < 0)
- return err;
-
- return 0;
-}
-
int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
{
struct tegra_rgb *rgb = to_rgb(dc->rgb);
diff --git a/drivers/gpu/host1x/host1x.h b/drivers/gpu/host1x/host1x.h
new file mode 100644
index 0000000..a2bc1e6
--- /dev/null
+++ b/drivers/gpu/host1x/host1x.h
@@ -0,0 +1,30 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2009-2013, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __LINUX_HOST1X_H
+#define __LINUX_HOST1X_H
+
+enum host1x_class {
+ HOST1X_CLASS_HOST1X = 0x1,
+ HOST1X_CLASS_GR2D = 0x51,
+ HOST1X_CLASS_GR2D_SB = 0x52
+};
+
+#endif
diff --git a/drivers/gpu/host1x/host1x_bo.h b/drivers/gpu/host1x/host1x_bo.h
new file mode 100644
index 0000000..4c1f10b
--- /dev/null
+++ b/drivers/gpu/host1x/host1x_bo.h
@@ -0,0 +1,87 @@
+/*
+ * Tegra host1x Memory Management Abstraction header
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _HOST1X_BO_H
+#define _HOST1X_BO_H
+
+struct host1x_bo;
+
+struct host1x_bo_ops {
+ struct host1x_bo *(*get)(struct host1x_bo *bo);
+ void (*put)(struct host1x_bo *bo);
+ dma_addr_t (*pin)(struct host1x_bo *bo, struct sg_table **sgt);
+ void (*unpin)(struct host1x_bo *bo, struct sg_table *sgt);
+ void *(*mmap)(struct host1x_bo *bo);
+ void (*munmap)(struct host1x_bo *bo, void *addr);
+ void *(*kmap)(struct host1x_bo *bo, unsigned int pagenum);
+ void (*kunmap)(struct host1x_bo *bo, unsigned int pagenum, void *addr);
+};
+
+struct host1x_bo {
+ const struct host1x_bo_ops *ops;
+};
+
+static inline void host1x_bo_init(struct host1x_bo *bo,
+ const struct host1x_bo_ops *ops)
+{
+ bo->ops = ops;
+}
+
+static inline struct host1x_bo *host1x_bo_get(struct host1x_bo *bo)
+{
+ return bo->ops->get(bo);
+}
+
+static inline void host1x_bo_put(struct host1x_bo *bo)
+{
+ bo->ops->put(bo);
+}
+
+static inline dma_addr_t host1x_bo_pin(struct host1x_bo *bo,
+ struct sg_table **sgt)
+{
+ return bo->ops->pin(bo, sgt);
+}
+
+static inline void host1x_bo_unpin(struct host1x_bo *bo, struct sg_table *sgt)
+{
+ bo->ops->unpin(bo, sgt);
+}
+
+static inline void *host1x_bo_mmap(struct host1x_bo *bo)
+{
+ return bo->ops->mmap(bo);
+}
+
+static inline void host1x_bo_munmap(struct host1x_bo *bo, void *addr)
+{
+ bo->ops->munmap(bo, addr);
+}
+
+static inline void *host1x_bo_kmap(struct host1x_bo *bo, unsigned int pagenum)
+{
+ return bo->ops->kmap(bo, pagenum);
+}
+
+static inline void host1x_bo_kunmap(struct host1x_bo *bo,
+ unsigned int pagenum, void *addr)
+{
+ bo->ops->kunmap(bo, pagenum, addr);
+}
+
+#endif
diff --git a/drivers/gpu/host1x/bus.h b/drivers/gpu/host1x/host1x_client.h
index 4099e99..9b85f10 100644
--- a/drivers/gpu/host1x/bus.h
+++ b/drivers/gpu/host1x/host1x_client.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012-2013, NVIDIA Corporation
+ * Copyright (c) 2013, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -15,15 +14,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef HOST1X_BUS_H
-#define HOST1X_BUS_H
+#ifndef HOST1X_CLIENT_H
+#define HOST1X_CLIENT_H
-struct host1x;
+struct device;
+struct platform_device;
-int host1x_bus_init(void);
-void host1x_bus_exit(void);
+#ifdef CONFIG_DRM_TEGRA
+int host1x_drm_alloc(struct platform_device *pdev);
+#else
+static inline int host1x_drm_alloc(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif
-int host1x_register(struct host1x *host1x);
-int host1x_unregister(struct host1x *host1x);
+void host1x_set_drm_data(struct device *dev, void *data);
+void *host1x_get_drm_data(struct device *dev);
#endif
diff --git a/drivers/gpu/host1x/hw/Makefile b/drivers/gpu/host1x/hw/Makefile
new file mode 100644
index 0000000..9b50863
--- /dev/null
+++ b/drivers/gpu/host1x/hw/Makefile
@@ -0,0 +1,6 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-hw-objs = \
+ host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x-hw.o
diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c
index 6b09b71..2ee4ad5 100644
--- a/drivers/gpu/host1x/hw/cdma_hw.c
+++ b/drivers/gpu/host1x/hw/cdma_hw.c
@@ -20,10 +20,10 @@
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
-#include "../cdma.h"
-#include "../channel.h"
-#include "../dev.h"
-#include "../debug.h"
+#include "cdma.h"
+#include "channel.h"
+#include "dev.h"
+#include "debug.h"
/*
* Put the restart at the end of pushbuffer memor
@@ -54,8 +54,8 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr,
u32 *p = (u32 *)((u32)pb->mapped + getptr);
*(p++) = HOST1X_OPCODE_NOP;
*(p++) = HOST1X_OPCODE_NOP;
- dev_dbg(host1x->dev, "%s: NOP at %#llx\n", __func__,
- (u64)pb->phys + getptr);
+ dev_dbg(host1x->dev, "%s: NOP at 0x%x\n", __func__,
+ pb->phys + getptr);
getptr = (getptr + 8) & (pb->size_bytes - 1);
}
wmb();
diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c
index 4608257..ee19962 100644
--- a/drivers/gpu/host1x/hw/channel_hw.c
+++ b/drivers/gpu/host1x/hw/channel_hw.c
@@ -16,15 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/host1x.h>
#include <linux/slab.h>
-
#include <trace/events/host1x.h>
-#include "../channel.h"
-#include "../dev.h"
-#include "../intr.h"
-#include "../job.h"
+#include "host1x.h"
+#include "host1x_bo.h"
+#include "channel.h"
+#include "dev.h"
+#include "intr.h"
+#include "job.h"
#define HOST1X_CHANNEL_SIZE 16384
#define TRACE_MAX_LENGTH 128U
@@ -67,22 +67,6 @@ static void submit_gathers(struct host1x_job *job)
}
}
-static inline void synchronize_syncpt_base(struct host1x_job *job)
-{
- struct host1x *host = dev_get_drvdata(job->channel->dev->parent);
- struct host1x_syncpt *sp = host->syncpt + job->syncpt_id;
- u32 id, value;
-
- value = host1x_syncpt_read_max(sp);
- id = sp->base->id;
-
- host1x_cdma_push(&job->channel->cdma,
- host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
- HOST1X_UCLASS_LOAD_SYNCPT_BASE, 1),
- HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(id) |
- HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value));
-}
-
static int channel_submit(struct host1x_job *job)
{
struct host1x_channel *ch = job->channel;
@@ -134,10 +118,6 @@ static int channel_submit(struct host1x_job *job)
host1x_syncpt_read_max(sp)));
}
- /* Synchronize base register to allow using it for relative waiting */
- if (sp->base)
- synchronize_syncpt_base(job);
-
syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs);
job->syncpt_end = syncval;
diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c
index f72c873..334c038 100644
--- a/drivers/gpu/host1x/hw/debug_hw.c
+++ b/drivers/gpu/host1x/hw/debug_hw.c
@@ -15,10 +15,18 @@
*
*/
-#include "../dev.h"
-#include "../debug.h"
-#include "../cdma.h"
-#include "../channel.h"
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+
+#include <linux/io.h>
+
+#include "dev.h"
+#include "debug.h"
+#include "cdma.h"
+#include "channel.h"
+#include "host1x_bo.h"
#define HOST1X_DEBUG_MAX_PAGE_OFFSET 102400
@@ -163,8 +171,8 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
continue;
}
- host1x_debug_output(o, " GATHER at %#llx+%04x, %d words\n",
- (u64)g->base, g->offset, g->words);
+ host1x_debug_output(o, " GATHER at %08x+%04x, %d words\n",
+ g->base, g->offset, g->words);
show_gather(o, g->base + g->offset, g->words, cdma,
g->base, mapped);
diff --git a/drivers/gpu/host1x/hw/host1x01.c b/drivers/gpu/host1x/hw/host1x01.c
index 859b73b..a14e91c 100644
--- a/drivers/gpu/host1x/hw/host1x01.c
+++ b/drivers/gpu/host1x/hw/host1x01.c
@@ -17,17 +17,17 @@
*/
/* include hw specification */
-#include "host1x01.h"
-#include "host1x01_hardware.h"
+#include "hw/host1x01.h"
+#include "hw/host1x01_hardware.h"
/* include code */
-#include "cdma_hw.c"
-#include "channel_hw.c"
-#include "debug_hw.c"
-#include "intr_hw.c"
-#include "syncpt_hw.c"
+#include "hw/cdma_hw.c"
+#include "hw/channel_hw.c"
+#include "hw/debug_hw.c"
+#include "hw/intr_hw.c"
+#include "hw/syncpt_hw.c"
-#include "../dev.h"
+#include "dev.h"
int host1x01_init(struct host1x *host)
{
diff --git a/drivers/gpu/host1x/hw/host1x02.c b/drivers/gpu/host1x/hw/host1x02.c
deleted file mode 100644
index e98caca..0000000
--- a/drivers/gpu/host1x/hw/host1x02.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Host1x init for Tegra114 SoCs
- *
- * Copyright (c) 2013 NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* include hw specification */
-#include "host1x01.h"
-#include "host1x01_hardware.h"
-
-/* include code */
-#include "cdma_hw.c"
-#include "channel_hw.c"
-#include "debug_hw.c"
-#include "intr_hw.c"
-#include "syncpt_hw.c"
-
-#include "../dev.h"
-
-int host1x02_init(struct host1x *host)
-{
- host->channel_op = &host1x_channel_ops;
- host->cdma_op = &host1x_cdma_ops;
- host->cdma_pb_op = &host1x_pushbuffer_ops;
- host->syncpt_op = &host1x_syncpt_ops;
- host->intr_op = &host1x_intr_ops;
- host->debug_op = &host1x_debug_ops;
-
- return 0;
-}
diff --git a/drivers/gpu/host1x/hw/host1x02.h b/drivers/gpu/host1x/hw/host1x02.h
deleted file mode 100644
index f748660..0000000
--- a/drivers/gpu/host1x/hw/host1x02.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Host1x init for Tegra114 SoCs
- *
- * Copyright (c) 2013 NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef HOST1X_HOST1X02_H
-#define HOST1X_HOST1X02_H
-
-struct host1x;
-
-int host1x02_init(struct host1x *host);
-
-#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x01_uclass.h b/drivers/gpu/host1x/hw/hw_host1x01_uclass.h
index f755359..42f3ce1 100644
--- a/drivers/gpu/host1x/hw/hw_host1x01_uclass.h
+++ b/drivers/gpu/host1x/hw/hw_host1x01_uclass.h
@@ -111,12 +111,6 @@ static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
}
#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \
host1x_uclass_wait_syncpt_base_offset_f(v)
-static inline u32 host1x_uclass_load_syncpt_base_r(void)
-{
- return 0xb;
-}
-#define HOST1X_UCLASS_LOAD_SYNCPT_BASE \
- host1x_uclass_load_syncpt_base_r()
static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
{
return (v & 0xff) << 24;
diff --git a/drivers/gpu/host1x/hw/hw_host1x02_channel.h b/drivers/gpu/host1x/hw/hw_host1x02_channel.h
deleted file mode 100644
index e490bcd..0000000
--- a/drivers/gpu/host1x/hw/hw_host1x02_channel.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2013 NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
- /*
- * Function naming determines intended use:
- *
- * <x>_r(void) : Returns the offset for register <x>.
- *
- * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
- *
- * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
- *
- * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
- * and masked to place it at field <y> of register <x>. This value
- * can be |'d with others to produce a full register value for
- * register <x>.
- *
- * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
- * value can be ~'d and then &'d to clear the value of field <y> for
- * register <x>.
- *
- * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
- * to place it at field <y> of register <x>. This value can be |'d
- * with others to produce a full register value for <x>.
- *
- * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
- * <x> value 'r' after being shifted to place its LSB at bit 0.
- * This value is suitable for direct comparison with other unshifted
- * values appropriate for use in field <y> of register <x>.
- *
- * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
- * field <y> of register <x>. This value is suitable for direct
- * comparison with unshifted values appropriate for use in field <y>
- * of register <x>.
- */
-
-#ifndef HOST1X_HW_HOST1X02_CHANNEL_H
-#define HOST1X_HW_HOST1X02_CHANNEL_H
-
-static inline u32 host1x_channel_fifostat_r(void)
-{
- return 0x0;
-}
-#define HOST1X_CHANNEL_FIFOSTAT \
- host1x_channel_fifostat_r()
-static inline u32 host1x_channel_fifostat_cfempty_v(u32 r)
-{
- return (r >> 11) & 0x1;
-}
-#define HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(r) \
- host1x_channel_fifostat_cfempty_v(r)
-static inline u32 host1x_channel_dmastart_r(void)
-{
- return 0x14;
-}
-#define HOST1X_CHANNEL_DMASTART \
- host1x_channel_dmastart_r()
-static inline u32 host1x_channel_dmaput_r(void)
-{
- return 0x18;
-}
-#define HOST1X_CHANNEL_DMAPUT \
- host1x_channel_dmaput_r()
-static inline u32 host1x_channel_dmaget_r(void)
-{
- return 0x1c;
-}
-#define HOST1X_CHANNEL_DMAGET \
- host1x_channel_dmaget_r()
-static inline u32 host1x_channel_dmaend_r(void)
-{
- return 0x20;
-}
-#define HOST1X_CHANNEL_DMAEND \
- host1x_channel_dmaend_r()
-static inline u32 host1x_channel_dmactrl_r(void)
-{
- return 0x24;
-}
-#define HOST1X_CHANNEL_DMACTRL \
- host1x_channel_dmactrl_r()
-static inline u32 host1x_channel_dmactrl_dmastop(void)
-{
- return 1 << 0;
-}
-#define HOST1X_CHANNEL_DMACTRL_DMASTOP \
- host1x_channel_dmactrl_dmastop()
-static inline u32 host1x_channel_dmactrl_dmastop_v(u32 r)
-{
- return (r >> 0) & 0x1;
-}
-#define HOST1X_CHANNEL_DMACTRL_DMASTOP_V(r) \
- host1x_channel_dmactrl_dmastop_v(r)
-static inline u32 host1x_channel_dmactrl_dmagetrst(void)
-{
- return 1 << 1;
-}
-#define HOST1X_CHANNEL_DMACTRL_DMAGETRST \
- host1x_channel_dmactrl_dmagetrst()
-static inline u32 host1x_channel_dmactrl_dmainitget(void)
-{
- return 1 << 2;
-}
-#define HOST1X_CHANNEL_DMACTRL_DMAINITGET \
- host1x_channel_dmactrl_dmainitget()
-
-#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x02_sync.h b/drivers/gpu/host1x/hw/hw_host1x02_sync.h
deleted file mode 100644
index 4495401..0000000
--- a/drivers/gpu/host1x/hw/hw_host1x02_sync.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (c) 2013 NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
- /*
- * Function naming determines intended use:
- *
- * <x>_r(void) : Returns the offset for register <x>.
- *
- * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
- *
- * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
- *
- * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
- * and masked to place it at field <y> of register <x>. This value
- * can be |'d with others to produce a full register value for
- * register <x>.
- *
- * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
- * value can be ~'d and then &'d to clear the value of field <y> for
- * register <x>.
- *
- * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
- * to place it at field <y> of register <x>. This value can be |'d
- * with others to produce a full register value for <x>.
- *
- * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
- * <x> value 'r' after being shifted to place its LSB at bit 0.
- * This value is suitable for direct comparison with other unshifted
- * values appropriate for use in field <y> of register <x>.
- *
- * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
- * field <y> of register <x>. This value is suitable for direct
- * comparison with unshifted values appropriate for use in field <y>
- * of register <x>.
- */
-
-#ifndef HOST1X_HW_HOST1X02_SYNC_H
-#define HOST1X_HW_HOST1X02_SYNC_H
-
-#define REGISTER_STRIDE 4
-
-static inline u32 host1x_sync_syncpt_r(unsigned int id)
-{
- return 0x400 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_SYNCPT(id) \
- host1x_sync_syncpt_r(id)
-static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(unsigned int id)
-{
- return 0x40 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id) \
- host1x_sync_syncpt_thresh_cpu0_int_status_r(id)
-static inline u32 host1x_sync_syncpt_thresh_int_disable_r(unsigned int id)
-{
- return 0x60 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id) \
- host1x_sync_syncpt_thresh_int_disable_r(id)
-static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(unsigned int id)
-{
- return 0x68 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id) \
- host1x_sync_syncpt_thresh_int_enable_cpu0_r(id)
-static inline u32 host1x_sync_cf_setup_r(unsigned int channel)
-{
- return 0x80 + channel * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_CF_SETUP(channel) \
- host1x_sync_cf_setup_r(channel)
-static inline u32 host1x_sync_cf_setup_base_v(u32 r)
-{
- return (r >> 0) & 0x3ff;
-}
-#define HOST1X_SYNC_CF_SETUP_BASE_V(r) \
- host1x_sync_cf_setup_base_v(r)
-static inline u32 host1x_sync_cf_setup_limit_v(u32 r)
-{
- return (r >> 16) & 0x3ff;
-}
-#define HOST1X_SYNC_CF_SETUP_LIMIT_V(r) \
- host1x_sync_cf_setup_limit_v(r)
-static inline u32 host1x_sync_cmdproc_stop_r(void)
-{
- return 0xac;
-}
-#define HOST1X_SYNC_CMDPROC_STOP \
- host1x_sync_cmdproc_stop_r()
-static inline u32 host1x_sync_ch_teardown_r(void)
-{
- return 0xb0;
-}
-#define HOST1X_SYNC_CH_TEARDOWN \
- host1x_sync_ch_teardown_r()
-static inline u32 host1x_sync_usec_clk_r(void)
-{
- return 0x1a4;
-}
-#define HOST1X_SYNC_USEC_CLK \
- host1x_sync_usec_clk_r()
-static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
-{
- return 0x1a8;
-}
-#define HOST1X_SYNC_CTXSW_TIMEOUT_CFG \
- host1x_sync_ctxsw_timeout_cfg_r()
-static inline u32 host1x_sync_ip_busy_timeout_r(void)
-{
- return 0x1bc;
-}
-#define HOST1X_SYNC_IP_BUSY_TIMEOUT \
- host1x_sync_ip_busy_timeout_r()
-static inline u32 host1x_sync_mlock_owner_r(unsigned int id)
-{
- return 0x340 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_MLOCK_OWNER(id) \
- host1x_sync_mlock_owner_r(id)
-static inline u32 host1x_sync_mlock_owner_chid_f(u32 v)
-{
- return (v & 0xf) << 8;
-}
-#define HOST1X_SYNC_MLOCK_OWNER_CHID_F(v) \
- host1x_sync_mlock_owner_chid_f(v)
-static inline u32 host1x_sync_mlock_owner_cpu_owns_v(u32 r)
-{
- return (r >> 1) & 0x1;
-}
-#define HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(r) \
- host1x_sync_mlock_owner_cpu_owns_v(r)
-static inline u32 host1x_sync_mlock_owner_ch_owns_v(u32 r)
-{
- return (r >> 0) & 0x1;
-}
-#define HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(r) \
- host1x_sync_mlock_owner_ch_owns_v(r)
-static inline u32 host1x_sync_syncpt_int_thresh_r(unsigned int id)
-{
- return 0x500 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_SYNCPT_INT_THRESH(id) \
- host1x_sync_syncpt_int_thresh_r(id)
-static inline u32 host1x_sync_syncpt_base_r(unsigned int id)
-{
- return 0x600 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_SYNCPT_BASE(id) \
- host1x_sync_syncpt_base_r(id)
-static inline u32 host1x_sync_syncpt_cpu_incr_r(unsigned int id)
-{
- return 0x700 + id * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_SYNCPT_CPU_INCR(id) \
- host1x_sync_syncpt_cpu_incr_r(id)
-static inline u32 host1x_sync_cbread_r(unsigned int channel)
-{
- return 0x720 + channel * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_CBREAD(channel) \
- host1x_sync_cbread_r(channel)
-static inline u32 host1x_sync_cfpeek_ctrl_r(void)
-{
- return 0x74c;
-}
-#define HOST1X_SYNC_CFPEEK_CTRL \
- host1x_sync_cfpeek_ctrl_r()
-static inline u32 host1x_sync_cfpeek_ctrl_addr_f(u32 v)
-{
- return (v & 0x3ff) << 0;
-}
-#define HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(v) \
- host1x_sync_cfpeek_ctrl_addr_f(v)
-static inline u32 host1x_sync_cfpeek_ctrl_channr_f(u32 v)
-{
- return (v & 0xf) << 16;
-}
-#define HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(v) \
- host1x_sync_cfpeek_ctrl_channr_f(v)
-static inline u32 host1x_sync_cfpeek_ctrl_ena_f(u32 v)
-{
- return (v & 0x1) << 31;
-}
-#define HOST1X_SYNC_CFPEEK_CTRL_ENA_F(v) \
- host1x_sync_cfpeek_ctrl_ena_f(v)
-static inline u32 host1x_sync_cfpeek_read_r(void)
-{
- return 0x750;
-}
-#define HOST1X_SYNC_CFPEEK_READ \
- host1x_sync_cfpeek_read_r()
-static inline u32 host1x_sync_cfpeek_ptrs_r(void)
-{
- return 0x754;
-}
-#define HOST1X_SYNC_CFPEEK_PTRS \
- host1x_sync_cfpeek_ptrs_r()
-static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(u32 r)
-{
- return (r >> 0) & 0x3ff;
-}
-#define HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(r) \
- host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(r)
-static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(u32 r)
-{
- return (r >> 16) & 0x3ff;
-}
-#define HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(r) \
- host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(r)
-static inline u32 host1x_sync_cbstat_r(unsigned int channel)
-{
- return 0x758 + channel * REGISTER_STRIDE;
-}
-#define HOST1X_SYNC_CBSTAT(channel) \
- host1x_sync_cbstat_r(channel)
-static inline u32 host1x_sync_cbstat_cboffset_v(u32 r)
-{
- return (r >> 0) & 0xffff;
-}
-#define HOST1X_SYNC_CBSTAT_CBOFFSET_V(r) \
- host1x_sync_cbstat_cboffset_v(r)
-static inline u32 host1x_sync_cbstat_cbclass_v(u32 r)
-{
- return (r >> 16) & 0x3ff;
-}
-#define HOST1X_SYNC_CBSTAT_CBCLASS_V(r) \
- host1x_sync_cbstat_cbclass_v(r)
-
-#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x02_uclass.h b/drivers/gpu/host1x/hw/hw_host1x02_uclass.h
deleted file mode 100644
index a3b3c98..0000000
--- a/drivers/gpu/host1x/hw/hw_host1x02_uclass.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2013 NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
- /*
- * Function naming determines intended use:
- *
- * <x>_r(void) : Returns the offset for register <x>.
- *
- * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
- *
- * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
- *
- * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
- * and masked to place it at field <y> of register <x>. This value
- * can be |'d with others to produce a full register value for
- * register <x>.
- *
- * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
- * value can be ~'d and then &'d to clear the value of field <y> for
- * register <x>.
- *
- * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
- * to place it at field <y> of register <x>. This value can be |'d
- * with others to produce a full register value for <x>.
- *
- * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
- * <x> value 'r' after being shifted to place its LSB at bit 0.
- * This value is suitable for direct comparison with other unshifted
- * values appropriate for use in field <y> of register <x>.
- *
- * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
- * field <y> of register <x>. This value is suitable for direct
- * comparison with unshifted values appropriate for use in field <y>
- * of register <x>.
- */
-
-#ifndef HOST1X_HW_HOST1X02_UCLASS_H
-#define HOST1X_HW_HOST1X02_UCLASS_H
-
-static inline u32 host1x_uclass_incr_syncpt_r(void)
-{
- return 0x0;
-}
-#define HOST1X_UCLASS_INCR_SYNCPT \
- host1x_uclass_incr_syncpt_r()
-static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
-{
- return (v & 0xff) << 8;
-}
-#define HOST1X_UCLASS_INCR_SYNCPT_COND_F(v) \
- host1x_uclass_incr_syncpt_cond_f(v)
-static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
-{
- return (v & 0xff) << 0;
-}
-#define HOST1X_UCLASS_INCR_SYNCPT_INDX_F(v) \
- host1x_uclass_incr_syncpt_indx_f(v)
-static inline u32 host1x_uclass_wait_syncpt_r(void)
-{
- return 0x8;
-}
-#define HOST1X_UCLASS_WAIT_SYNCPT \
- host1x_uclass_wait_syncpt_r()
-static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
-{
- return (v & 0xff) << 24;
-}
-#define HOST1X_UCLASS_WAIT_SYNCPT_INDX_F(v) \
- host1x_uclass_wait_syncpt_indx_f(v)
-static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
-{
- return (v & 0xffffff) << 0;
-}
-#define HOST1X_UCLASS_WAIT_SYNCPT_THRESH_F(v) \
- host1x_uclass_wait_syncpt_thresh_f(v)
-static inline u32 host1x_uclass_wait_syncpt_base_r(void)
-{
- return 0x9;
-}
-#define HOST1X_UCLASS_WAIT_SYNCPT_BASE \
- host1x_uclass_wait_syncpt_base_r()
-static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
-{
- return (v & 0xff) << 24;
-}
-#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_INDX_F(v) \
- host1x_uclass_wait_syncpt_base_indx_f(v)
-static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
-{
- return (v & 0xff) << 16;
-}
-#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_BASE_INDX_F(v) \
- host1x_uclass_wait_syncpt_base_base_indx_f(v)
-static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
-{
- return (v & 0xffff) << 0;
-}
-#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \
- host1x_uclass_wait_syncpt_base_offset_f(v)
-static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
-{
- return (v & 0xff) << 24;
-}
-#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(v) \
- host1x_uclass_load_syncpt_base_base_indx_f(v)
-static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
-{
- return (v & 0xffffff) << 0;
-}
-#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(v) \
- host1x_uclass_load_syncpt_base_value_f(v)
-static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
-{
- return (v & 0xff) << 24;
-}
-#define HOST1X_UCLASS_INCR_SYNCPT_BASE_BASE_INDX_F(v) \
- host1x_uclass_incr_syncpt_base_base_indx_f(v)
-static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
-{
- return (v & 0xffffff) << 0;
-}
-#define HOST1X_UCLASS_INCR_SYNCPT_BASE_OFFSET_F(v) \
- host1x_uclass_incr_syncpt_base_offset_f(v)
-static inline u32 host1x_uclass_indoff_r(void)
-{
- return 0x2d;
-}
-#define HOST1X_UCLASS_INDOFF \
- host1x_uclass_indoff_r()
-static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
-{
- return (v & 0xf) << 28;
-}
-#define HOST1X_UCLASS_INDOFF_INDBE_F(v) \
- host1x_uclass_indoff_indbe_f(v)
-static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
-{
- return (v & 0x1) << 27;
-}
-#define HOST1X_UCLASS_INDOFF_AUTOINC_F(v) \
- host1x_uclass_indoff_autoinc_f(v)
-static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
-{
- return (v & 0xff) << 18;
-}
-#define HOST1X_UCLASS_INDOFF_INDMODID_F(v) \
- host1x_uclass_indoff_indmodid_f(v)
-static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
-{
- return (v & 0xffff) << 2;
-}
-#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
- host1x_uclass_indoff_indroffset_f(v)
-static inline u32 host1x_uclass_indoff_rwn_read_v(void)
-{
- return 1;
-}
-#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
- host1x_uclass_indoff_indroffset_f(v)
-
-#endif
diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c
index b26dcc8..b592eef 100644
--- a/drivers/gpu/host1x/hw/intr_hw.c
+++ b/drivers/gpu/host1x/hw/intr_hw.c
@@ -22,8 +22,8 @@
#include <linux/io.h>
#include <asm/mach/irq.h>
-#include "../intr.h"
-#include "../dev.h"
+#include "intr.h"
+#include "dev.h"
/*
* Sync point threshold interrupt service function
diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c b/drivers/gpu/host1x/hw/syncpt_hw.c
index 56e8539..0cf6095 100644
--- a/drivers/gpu/host1x/hw/syncpt_hw.c
+++ b/drivers/gpu/host1x/hw/syncpt_hw.c
@@ -18,8 +18,8 @@
#include <linux/io.h>
-#include "../dev.h"
-#include "../syncpt.h"
+#include "dev.h"
+#include "syncpt.h"
/*
* Write the current syncpoint value back to hw.
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index de5ec33..c4e1050 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -18,7 +18,6 @@
#include <linux/dma-mapping.h>
#include <linux/err.h>
-#include <linux/host1x.h>
#include <linux/kref.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
@@ -28,6 +27,7 @@
#include "channel.h"
#include "dev.h"
+#include "host1x_bo.h"
#include "job.h"
#include "syncpt.h"
@@ -264,7 +264,7 @@ static unsigned int do_relocs(struct host1x_job *job, struct host1x_bo *cmdbuf)
}
static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf,
- unsigned int offset)
+ unsigned int offset)
{
offset *= sizeof(u32);
@@ -281,7 +281,7 @@ struct host1x_firewall {
unsigned int num_relocs;
struct host1x_reloc *reloc;
- struct host1x_bo *cmdbuf;
+ struct host1x_bo *cmdbuf_id;
unsigned int offset;
u32 words;
@@ -291,37 +291,25 @@ struct host1x_firewall {
u32 count;
};
-static int check_register(struct host1x_firewall *fw, unsigned long offset)
-{
- if (fw->job->is_addr_reg(fw->dev, fw->class, offset)) {
- if (!fw->num_relocs)
- return -EINVAL;
-
- if (!check_reloc(fw->reloc, fw->cmdbuf, fw->offset))
- return -EINVAL;
-
- fw->num_relocs--;
- fw->reloc++;
- }
-
- return 0;
-}
-
static int check_mask(struct host1x_firewall *fw)
{
u32 mask = fw->mask;
u32 reg = fw->reg;
- int ret;
while (mask) {
if (fw->words == 0)
return -EINVAL;
if (mask & 1) {
- ret = check_register(fw, reg);
- if (ret < 0)
- return ret;
-
+ if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
+ if (!fw->num_relocs)
+ return -EINVAL;
+ if (!check_reloc(fw->reloc, fw->cmdbuf_id,
+ fw->offset))
+ return -EINVAL;
+ fw->reloc++;
+ fw->num_relocs--;
+ }
fw->words--;
fw->offset++;
}
@@ -336,16 +324,19 @@ static int check_incr(struct host1x_firewall *fw)
{
u32 count = fw->count;
u32 reg = fw->reg;
- int ret;
while (count) {
if (fw->words == 0)
return -EINVAL;
- ret = check_register(fw, reg);
- if (ret < 0)
- return ret;
-
+ if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
+ if (!fw->num_relocs)
+ return -EINVAL;
+ if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset))
+ return -EINVAL;
+ fw->reloc++;
+ fw->num_relocs--;
+ }
reg++;
fw->words--;
fw->offset++;
@@ -357,17 +348,21 @@ static int check_incr(struct host1x_firewall *fw)
static int check_nonincr(struct host1x_firewall *fw)
{
+ int is_addr_reg = fw->job->is_addr_reg(fw->dev, fw->class, fw->reg);
u32 count = fw->count;
- int ret;
while (count) {
if (fw->words == 0)
return -EINVAL;
- ret = check_register(fw, fw->reg);
- if (ret < 0)
- return ret;
-
+ if (is_addr_reg) {
+ if (!fw->num_relocs)
+ return -EINVAL;
+ if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset))
+ return -EINVAL;
+ fw->reloc++;
+ fw->num_relocs--;
+ }
fw->words--;
fw->offset++;
count--;
@@ -386,7 +381,7 @@ static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g)
return 0;
fw->words = g->words;
- fw->cmdbuf = g->bo;
+ fw->cmdbuf_id = g->bo;
fw->offset = 0;
while (fw->words && !err) {
@@ -441,6 +436,10 @@ static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g)
}
}
+ /* No relocs should remain at this point */
+ if (fw->num_relocs)
+ err = -EINVAL;
+
out:
return err;
}
@@ -494,10 +493,6 @@ static inline int copy_gathers(struct host1x_job *job, struct device *dev)
offset += g->words * sizeof(u32);
}
- /* No relocs should remain at this point */
- if (fw.num_relocs)
- return -EINVAL;
-
return 0;
}
diff --git a/drivers/gpu/host1x/job.h b/drivers/gpu/host1x/job.h
index 33a697d..fba45f2 100644
--- a/drivers/gpu/host1x/job.h
+++ b/drivers/gpu/host1x/job.h
@@ -34,6 +34,15 @@ struct host1x_cmdbuf {
u32 pad;
};
+struct host1x_reloc {
+ struct host1x_bo *cmdbuf;
+ u32 cmdbuf_offset;
+ struct host1x_bo *target;
+ u32 target_offset;
+ u32 shift;
+ u32 pad;
+};
+
struct host1x_waitchk {
struct host1x_bo *bo;
u32 offset;
@@ -47,6 +56,105 @@ struct host1x_job_unpin_data {
};
/*
+ * Each submit is tracked as a host1x_job.
+ */
+struct host1x_job {
+ /* When refcount goes to zero, job can be freed */
+ struct kref ref;
+
+ /* List entry */
+ struct list_head list;
+
+ /* Channel where job is submitted to */
+ struct host1x_channel *channel;
+
+ u32 client;
+
+ /* Gathers and their memory */
+ struct host1x_job_gather *gathers;
+ unsigned int num_gathers;
+
+ /* Wait checks to be processed at submit time */
+ struct host1x_waitchk *waitchk;
+ unsigned int num_waitchk;
+ u32 waitchk_mask;
+
+ /* Array of handles to be pinned & unpinned */
+ struct host1x_reloc *relocarray;
+ unsigned int num_relocs;
+ struct host1x_job_unpin_data *unpins;
+ unsigned int num_unpins;
+
+ dma_addr_t *addr_phys;
+ dma_addr_t *gather_addr_phys;
+ dma_addr_t *reloc_addr_phys;
+
+ /* Sync point id, number of increments and end related to the submit */
+ u32 syncpt_id;
+ u32 syncpt_incrs;
+ u32 syncpt_end;
+
+ /* Maximum time to wait for this job */
+ unsigned int timeout;
+
+ /* Index and number of slots used in the push buffer */
+ unsigned int first_get;
+ unsigned int num_slots;
+
+ /* Copy of gathers */
+ size_t gather_copy_size;
+ dma_addr_t gather_copy;
+ u8 *gather_copy_mapped;
+
+ /* Check if register is marked as an address reg */
+ int (*is_addr_reg)(struct device *dev, u32 reg, u32 class);
+
+ /* Request a SETCLASS to this class */
+ u32 class;
+
+ /* Add a channel wait for previous ops to complete */
+ bool serialize;
+};
+/*
+ * Allocate memory for a job. Just enough memory will be allocated to
+ * accomodate the submit.
+ */
+struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,
+ u32 num_cmdbufs, u32 num_relocs,
+ u32 num_waitchks);
+
+/*
+ * Add a gather to a job.
+ */
+void host1x_job_add_gather(struct host1x_job *job, struct host1x_bo *mem_id,
+ u32 words, u32 offset);
+
+/*
+ * Increment reference going to host1x_job.
+ */
+struct host1x_job *host1x_job_get(struct host1x_job *job);
+
+/*
+ * Decrement reference job, free if goes to zero.
+ */
+void host1x_job_put(struct host1x_job *job);
+
+/*
+ * Pin memory related to job. This handles relocation of addresses to the
+ * host1x address space. Handles both the gather memory and any other memory
+ * referred to from the gather buffers.
+ *
+ * Handles also patching out host waits that would wait for an expired sync
+ * point value.
+ */
+int host1x_job_pin(struct host1x_job *job, struct device *dev);
+
+/*
+ * Unpin memory related to job.
+ */
+void host1x_job_unpin(struct host1x_job *job);
+
+/*
* Dump contents of job to debug output.
*/
void host1x_job_dump(struct device *dev, struct host1x_job *job);
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index 159c479..409745b 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -30,32 +30,9 @@
#define SYNCPT_CHECK_PERIOD (2 * HZ)
#define MAX_STUCK_CHECK_COUNT 15
-static struct host1x_syncpt_base *
-host1x_syncpt_base_request(struct host1x *host)
-{
- struct host1x_syncpt_base *bases = host->bases;
- unsigned int i;
-
- for (i = 0; i < host->info->nb_bases; i++)
- if (!bases[i].requested)
- break;
-
- if (i >= host->info->nb_bases)
- return NULL;
-
- bases[i].requested = true;
- return &bases[i];
-}
-
-static void host1x_syncpt_base_free(struct host1x_syncpt_base *base)
-{
- if (base)
- base->requested = false;
-}
-
-static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
- struct device *dev,
- unsigned long flags)
+static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host,
+ struct device *dev,
+ bool client_managed)
{
int i;
struct host1x_syncpt *sp = host->syncpt;
@@ -67,12 +44,6 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
if (i >= host->info->nb_pts)
return NULL;
- if (flags & HOST1X_SYNCPT_HAS_BASE) {
- sp->base = host1x_syncpt_base_request(host);
- if (!sp->base)
- return NULL;
- }
-
name = kasprintf(GFP_KERNEL, "%02d-%s", sp->id,
dev ? dev_name(dev) : NULL);
if (!name)
@@ -80,11 +51,7 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
sp->dev = dev;
sp->name = name;
-
- if (flags & HOST1X_SYNCPT_CLIENT_MANAGED)
- sp->client_managed = true;
- else
- sp->client_managed = false;
+ sp->client_managed = client_managed;
return sp;
}
@@ -336,35 +303,25 @@ int host1x_syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr)
int host1x_syncpt_init(struct host1x *host)
{
- struct host1x_syncpt_base *bases;
struct host1x_syncpt *syncpt;
int i;
syncpt = devm_kzalloc(host->dev, sizeof(*syncpt) * host->info->nb_pts,
- GFP_KERNEL);
+ GFP_KERNEL);
if (!syncpt)
return -ENOMEM;
- bases = devm_kzalloc(host->dev, sizeof(*bases) * host->info->nb_bases,
- GFP_KERNEL);
- if (!bases)
- return -ENOMEM;
-
- for (i = 0; i < host->info->nb_pts; i++) {
+ for (i = 0; i < host->info->nb_pts; ++i) {
syncpt[i].id = i;
syncpt[i].host = host;
}
- for (i = 0; i < host->info->nb_bases; i++)
- bases[i].id = i;
-
host->syncpt = syncpt;
- host->bases = bases;
host1x_syncpt_restore(host);
/* Allocate sync point to use for clearing waits for expired fences */
- host->nop_sp = host1x_syncpt_alloc(host, NULL, 0);
+ host->nop_sp = _host1x_syncpt_alloc(host, NULL, false);
if (!host->nop_sp)
return -ENOMEM;
@@ -372,10 +329,10 @@ int host1x_syncpt_init(struct host1x *host)
}
struct host1x_syncpt *host1x_syncpt_request(struct device *dev,
- unsigned long flags)
+ bool client_managed)
{
struct host1x *host = dev_get_drvdata(dev->parent);
- return host1x_syncpt_alloc(host, dev, flags);
+ return _host1x_syncpt_alloc(host, dev, client_managed);
}
void host1x_syncpt_free(struct host1x_syncpt *sp)
@@ -383,9 +340,7 @@ void host1x_syncpt_free(struct host1x_syncpt *sp)
if (!sp)
return;
- host1x_syncpt_base_free(sp->base);
kfree(sp->name);
- sp->base = NULL;
sp->dev = NULL;
sp->name = NULL;
sp->client_managed = false;
@@ -399,25 +354,6 @@ void host1x_syncpt_deinit(struct host1x *host)
kfree(sp->name);
}
-/*
- * Read max. It indicates how many operations there are in queue, either in
- * channel or in a software thread.
- * */
-u32 host1x_syncpt_read_max(struct host1x_syncpt *sp)
-{
- smp_rmb();
- return (u32)atomic_read(&sp->max_val);
-}
-
-/*
- * Read min, which is a shadow of the current sync point value in hardware.
- */
-u32 host1x_syncpt_read_min(struct host1x_syncpt *sp)
-{
- smp_rmb();
- return (u32)atomic_read(&sp->min_val);
-}
-
int host1x_syncpt_nb_pts(struct host1x *host)
{
return host->info->nb_pts;
@@ -439,13 +375,3 @@ struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id)
return NULL;
return host->syncpt + id;
}
-
-struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp)
-{
- return sp ? sp->base : NULL;
-}
-
-u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base)
-{
- return base->id;
-}
diff --git a/drivers/gpu/host1x/syncpt.h b/drivers/gpu/host1x/syncpt.h
index 9056465..267c0b9 100644
--- a/drivers/gpu/host1x/syncpt.h
+++ b/drivers/gpu/host1x/syncpt.h
@@ -20,7 +20,6 @@
#define __HOST1X_SYNCPT_H
#include <linux/atomic.h>
-#include <linux/host1x.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -31,11 +30,6 @@ struct host1x;
/* Reserved for replacing an expired wait with a NOP */
#define HOST1X_SYNCPT_RESERVED 0
-struct host1x_syncpt_base {
- unsigned int id;
- bool requested;
-};
-
struct host1x_syncpt {
int id;
atomic_t min_val;
@@ -45,7 +39,6 @@ struct host1x_syncpt {
bool client_managed;
struct host1x *host;
struct device *dev;
- struct host1x_syncpt_base *base;
/* interrupt data */
struct host1x_syncpt_intr intr;
@@ -57,6 +50,25 @@ int host1x_syncpt_init(struct host1x *host);
/* Free sync point array */
void host1x_syncpt_deinit(struct host1x *host);
+/*
+ * Read max. It indicates how many operations there are in queue, either in
+ * channel or in a software thread.
+ * */
+static inline u32 host1x_syncpt_read_max(struct host1x_syncpt *sp)
+{
+ smp_rmb();
+ return (u32)atomic_read(&sp->max_val);
+}
+
+/*
+ * Read min, which is a shadow of the current sync point value in hardware.
+ */
+static inline u32 host1x_syncpt_read_min(struct host1x_syncpt *sp)
+{
+ smp_rmb();
+ return (u32)atomic_read(&sp->min_val);
+}
+
/* Return number of sync point supported. */
int host1x_syncpt_nb_pts(struct host1x *host);
@@ -100,6 +112,9 @@ static inline bool host1x_syncpt_idle(struct host1x_syncpt *sp)
return (min == max);
}
+/* Return pointer to struct denoting sync point id. */
+struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id);
+
/* Load current value from hardware to the shadow register. */
u32 host1x_syncpt_load(struct host1x_syncpt *sp);
@@ -115,9 +130,16 @@ void host1x_syncpt_restore(struct host1x *host);
/* Read current wait base value into shadow register and return it. */
u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp);
+/* Request incrementing a sync point. */
+int host1x_syncpt_incr(struct host1x_syncpt *sp);
+
/* Indicate future operations by incrementing the sync point max. */
u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs);
+/* Wait until sync point reaches a threshold value, or a timeout. */
+int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh,
+ long timeout, u32 *value);
+
/* Check if sync point id is valid. */
static inline int host1x_syncpt_is_valid(struct host1x_syncpt *sp)
{
@@ -127,4 +149,14 @@ static inline int host1x_syncpt_is_valid(struct host1x_syncpt *sp)
/* Patch a wait by replacing it with a wait for syncpt 0 value 0 */
int host1x_syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr);
+/* Return id of the sync point */
+u32 host1x_syncpt_id(struct host1x_syncpt *sp);
+
+/* Allocate a sync point for a device. */
+struct host1x_syncpt *host1x_syncpt_request(struct device *dev,
+ bool client_managed);
+
+/* Free a sync point. */
+void host1x_syncpt_free(struct host1x_syncpt *sp);
+
#endif