From c9fcf43ab8c77a220fd5515ae952c7f25f2f59a5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 15 Feb 2013 10:24:35 +0000 Subject: [PATCH] --- yaml --- r: 358331 b: refs/heads/master c: 50fdaae79abbfc4f04b5380ac5abf00fd448c5a5 h: refs/heads/master i: 358329: b3a271cc5e03c61aa4411b38e8d46f65209e40a4 358327: 59ac6ceef735d9f768f86253061501126f3834c4 v: v3 --- [refs] | 2 +- trunk/Documentation/thermal/nouveau_thermal | 81 --- trunk/drivers/char/agp/intel-gtt.c | 42 +- trunk/drivers/gpu/Makefile | 2 +- trunk/drivers/gpu/drm/Kconfig | 2 - trunk/drivers/gpu/drm/Makefile | 1 - trunk/drivers/gpu/drm/drm_crtc.c | 5 +- trunk/drivers/gpu/drm/drm_edid.c | 3 +- trunk/drivers/gpu/drm/drm_fb_cma_helper.c | 9 +- trunk/drivers/gpu/drm/i915/i915_debugfs.c | 13 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 1 - trunk/drivers/gpu/drm/i915/i915_drv.c | 13 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 24 +- trunk/drivers/gpu/drm/i915/i915_gem.c | 62 +-- trunk/drivers/gpu/drm/i915/i915_gem_context.c | 12 +- trunk/drivers/gpu/drm/i915/i915_gem_gtt.c | 23 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 104 ++-- trunk/drivers/gpu/drm/i915/i915_reg.h | 92 +--- trunk/drivers/gpu/drm/i915/intel_crt.c | 14 +- trunk/drivers/gpu/drm/i915/intel_ddi.c | 25 +- trunk/drivers/gpu/drm/i915/intel_display.c | 108 +--- trunk/drivers/gpu/drm/i915/intel_dp.c | 12 +- trunk/drivers/gpu/drm/i915/intel_drv.h | 4 - trunk/drivers/gpu/drm/i915/intel_hdmi.c | 10 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 80 ++- trunk/drivers/gpu/drm/i915/intel_panel.c | 13 +- trunk/drivers/gpu/drm/i915/intel_pm.c | 18 +- trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +- trunk/drivers/gpu/drm/i915/intel_sprite.c | 30 +- trunk/drivers/gpu/drm/nouveau/Kconfig | 5 +- trunk/drivers/gpu/drm/nouveau/Makefile | 29 +- .../gpu/drm/nouveau/core/core/client.c | 10 - .../drivers/gpu/drm/nouveau/core/core/enum.c | 11 +- .../drivers/gpu/drm/nouveau/core/core/event.c | 106 ---- .../gpu/drm/nouveau/core/engine/copy/nva3.c | 6 +- .../gpu/drm/nouveau/core/engine/crypt/nv84.c | 8 +- .../gpu/drm/nouveau/core/engine/crypt/nv98.c | 6 +- .../gpu/drm/nouveau/core/engine/disp/base.c | 52 -- .../gpu/drm/nouveau/core/engine/disp/dport.c | 346 ------------- .../gpu/drm/nouveau/core/engine/disp/dport.h | 78 --- .../gpu/drm/nouveau/core/engine/disp/nv04.c | 33 +- .../gpu/drm/nouveau/core/engine/disp/nv50.c | 371 ++++++-------- .../gpu/drm/nouveau/core/engine/disp/nv50.h | 37 +- .../gpu/drm/nouveau/core/engine/disp/nv84.c | 12 +- .../gpu/drm/nouveau/core/engine/disp/nv94.c | 24 +- .../gpu/drm/nouveau/core/engine/disp/nva0.c | 9 +- .../gpu/drm/nouveau/core/engine/disp/nva3.c | 24 +- .../gpu/drm/nouveau/core/engine/disp/nvd0.c | 309 ++++++----- .../gpu/drm/nouveau/core/engine/disp/nve0.c | 17 +- .../drm/nouveau/core/engine/disp/piornv50.c | 140 ----- .../drm/nouveau/core/engine/disp/sornv50.c | 25 + .../drm/nouveau/core/engine/disp/sornv94.c | 153 ++++-- .../drm/nouveau/core/engine/disp/sornvd0.c | 90 ++-- .../gpu/drm/nouveau/core/engine/fifo/base.c | 21 - .../gpu/drm/nouveau/core/engine/fifo/nv04.c | 187 ++++--- .../gpu/drm/nouveau/core/engine/fifo/nv50.c | 5 +- .../gpu/drm/nouveau/core/engine/fifo/nv84.c | 22 +- .../gpu/drm/nouveau/core/engine/fifo/nvc0.c | 109 +--- .../gpu/drm/nouveau/core/engine/fifo/nve0.c | 64 +-- .../gpu/drm/nouveau/core/engine/graph/nv04.c | 16 +- .../gpu/drm/nouveau/core/engine/graph/nv10.c | 16 +- .../gpu/drm/nouveau/core/engine/graph/nv20.c | 15 +- .../gpu/drm/nouveau/core/engine/graph/nv40.c | 16 +- .../gpu/drm/nouveau/core/engine/graph/nv50.c | 53 +- .../gpu/drm/nouveau/core/engine/graph/nvc0.c | 33 +- .../gpu/drm/nouveau/core/engine/graph/nve0.c | 44 +- .../gpu/drm/nouveau/core/engine/mpeg/nv31.c | 7 +- .../drm/nouveau/core/engine/software/nv50.c | 40 +- .../drm/nouveau/core/engine/software/nvc0.c | 29 +- .../gpu/drm/nouveau/core/include/core/class.h | 44 +- .../drm/nouveau/core/include/core/client.h | 3 +- .../drm/nouveau/core/include/core/device.h | 1 - .../gpu/drm/nouveau/core/include/core/enum.h | 3 +- .../gpu/drm/nouveau/core/include/core/event.h | 36 -- .../drm/nouveau/core/include/core/object.h | 12 +- .../drm/nouveau/core/include/core/printk.h | 3 +- .../drm/nouveau/core/include/engine/disp.h | 27 +- .../drm/nouveau/core/include/engine/fifo.h | 4 - .../nouveau/core/include/engine/software.h | 4 +- .../nouveau/core/include/subdev/bios/dcb.h | 3 - .../nouveau/core/include/subdev/bios/gpio.h | 11 +- .../nouveau/core/include/subdev/bios/i2c.h | 2 +- .../nouveau/core/include/subdev/bios/therm.h | 16 - .../nouveau/core/include/subdev/bios/xpio.h | 19 - .../gpu/drm/nouveau/core/include/subdev/bus.h | 41 -- .../drm/nouveau/core/include/subdev/gpio.h | 39 +- .../gpu/drm/nouveau/core/include/subdev/i2c.h | 127 +---- .../drm/nouveau/core/include/subdev/therm.h | 37 +- .../drm/nouveau/core/include/subdev/timer.h | 8 - trunk/drivers/gpu/drm/nouveau/core/os.h | 1 - .../gpu/drm/nouveau/core/subdev/bios/base.c | 2 +- .../gpu/drm/nouveau/core/subdev/bios/dcb.c | 32 +- .../gpu/drm/nouveau/core/subdev/bios/extdev.c | 2 +- .../gpu/drm/nouveau/core/subdev/bios/gpio.c | 11 +- .../gpu/drm/nouveau/core/subdev/bios/i2c.c | 15 +- .../gpu/drm/nouveau/core/subdev/bios/init.c | 15 +- .../gpu/drm/nouveau/core/subdev/bios/therm.c | 28 +- .../gpu/drm/nouveau/core/subdev/bios/xpio.c | 76 --- .../gpu/drm/nouveau/core/subdev/bus/nv04.c | 95 ---- .../gpu/drm/nouveau/core/subdev/bus/nv31.c | 112 ---- .../gpu/drm/nouveau/core/subdev/bus/nv50.c | 105 ---- .../gpu/drm/nouveau/core/subdev/bus/nvc0.c | 101 ---- .../gpu/drm/nouveau/core/subdev/device/base.c | 5 +- .../gpu/drm/nouveau/core/subdev/device/nv04.c | 7 +- .../gpu/drm/nouveau/core/subdev/device/nv10.c | 25 +- .../gpu/drm/nouveau/core/subdev/device/nv20.c | 13 +- .../gpu/drm/nouveau/core/subdev/device/nv30.c | 16 +- .../gpu/drm/nouveau/core/subdev/device/nv40.c | 50 +- .../gpu/drm/nouveau/core/subdev/device/nv50.c | 51 +- .../gpu/drm/nouveau/core/subdev/device/nvc0.c | 43 +- .../gpu/drm/nouveau/core/subdev/device/nve0.c | 22 +- .../drm/nouveau/core/subdev/devinit/nv50.c | 14 +- .../gpu/drm/nouveau/core/subdev/fb/nv50.c | 64 +-- .../gpu/drm/nouveau/core/subdev/gpio/base.c | 140 ++++- .../gpu/drm/nouveau/core/subdev/gpio/nv10.c | 40 +- .../gpu/drm/nouveau/core/subdev/gpio/nv50.c | 45 +- .../gpu/drm/nouveau/core/subdev/gpio/nvd0.c | 14 +- .../gpu/drm/nouveau/core/subdev/gpio/nve0.c | 131 ----- .../gpu/drm/nouveau/core/subdev/gpio/priv.h | 17 - .../gpu/drm/nouveau/core/subdev/i2c/anx9805.c | 279 ---------- .../gpu/drm/nouveau/core/subdev/i2c/aux.c | 154 +++++- .../gpu/drm/nouveau/core/subdev/i2c/base.c | 481 ++++++++++-------- .../gpu/drm/nouveau/core/subdev/i2c/bit.c | 18 +- .../gpu/drm/nouveau/core/subdev/i2c/nv04.c | 143 ------ .../gpu/drm/nouveau/core/subdev/i2c/nv4e.c | 135 ----- .../gpu/drm/nouveau/core/subdev/i2c/nv50.c | 149 ------ .../gpu/drm/nouveau/core/subdev/i2c/nv50.h | 32 -- .../gpu/drm/nouveau/core/subdev/i2c/nv94.c | 285 ----------- .../gpu/drm/nouveau/core/subdev/i2c/nvd0.c | 124 ----- .../gpu/drm/nouveau/core/subdev/mc/nv04.c | 2 +- .../gpu/drm/nouveau/core/subdev/mc/nv50.c | 1 - .../gpu/drm/nouveau/core/subdev/mc/nv98.c | 2 - .../gpu/drm/nouveau/core/subdev/mc/nvc0.c | 2 - .../gpu/drm/nouveau/core/subdev/mxm/mxms.c | 8 +- .../gpu/drm/nouveau/core/subdev/therm/base.c | 218 +------- .../gpu/drm/nouveau/core/subdev/therm/fan.c | 244 ++++----- .../drm/nouveau/core/subdev/therm/fannil.c | 54 -- .../drm/nouveau/core/subdev/therm/fanpwm.c | 107 ---- .../drm/nouveau/core/subdev/therm/fantog.c | 115 ----- .../gpu/drm/nouveau/core/subdev/therm/ic.c | 54 +- .../gpu/drm/nouveau/core/subdev/therm/nv40.c | 82 +-- .../gpu/drm/nouveau/core/subdev/therm/nv50.c | 199 +------- .../gpu/drm/nouveau/core/subdev/therm/nva3.c | 99 ---- .../gpu/drm/nouveau/core/subdev/therm/nvd0.c | 153 ------ .../gpu/drm/nouveau/core/subdev/therm/priv.h | 103 +--- .../gpu/drm/nouveau/core/subdev/therm/temp.c | 162 ------ .../gpu/drm/nouveau/core/subdev/timer/nv04.c | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_acpi.h | 2 +- .../gpu/drm/nouveau/nouveau_backlight.c | 2 - trunk/drivers/gpu/drm/nouveau/nouveau_bios.c | 130 +++-- trunk/drivers/gpu/drm/nouveau/nouveau_bios.h | 12 +- trunk/drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_chan.c | 5 +- .../gpu/drm/nouveau/nouveau_connector.c | 96 ++-- .../gpu/drm/nouveau/nouveau_connector.h | 10 +- .../drivers/gpu/drm/nouveau/nouveau_debugfs.c | 64 --- .../drivers/gpu/drm/nouveau/nouveau_debugfs.h | 22 - .../drivers/gpu/drm/nouveau/nouveau_display.c | 85 +++- .../drivers/gpu/drm/nouveau/nouveau_display.h | 3 + trunk/drivers/gpu/drm/nouveau/nouveau_dma.h | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_dp.c | 297 ++++++++++- trunk/drivers/gpu/drm/nouveau/nouveau_drm.c | 51 +- trunk/drivers/gpu/drm/nouveau/nouveau_drm.h | 2 - .../drivers/gpu/drm/nouveau/nouveau_encoder.h | 9 +- trunk/drivers/gpu/drm/nouveau/nouveau_fence.c | 103 +--- trunk/drivers/gpu/drm/nouveau/nouveau_fence.h | 42 +- trunk/drivers/gpu/drm/nouveau/nouveau_gem.c | 81 ++- trunk/drivers/gpu/drm/nouveau/nouveau_pm.c | 233 +-------- trunk/drivers/gpu/drm/nouveau/nv04_dfp.c | 4 +- trunk/drivers/gpu/drm/nouveau/nv04_display.c | 16 - trunk/drivers/gpu/drm/nouveau/nv04_display.h | 1 - trunk/drivers/gpu/drm/nouveau/nv04_fence.c | 6 +- trunk/drivers/gpu/drm/nouveau/nv10_fence.c | 118 ++++- trunk/drivers/gpu/drm/nouveau/nv10_fence.h | 19 - trunk/drivers/gpu/drm/nouveau/nv17_fence.c | 149 ------ trunk/drivers/gpu/drm/nouveau/nv50_display.c | 297 ++--------- trunk/drivers/gpu/drm/nouveau/nv50_fence.c | 36 +- trunk/drivers/gpu/drm/nouveau/nv84_fence.c | 214 +++----- trunk/drivers/gpu/drm/nouveau/nvc0_fence.c | 186 ++++++- trunk/drivers/gpu/drm/omapdrm/TODO | 23 - trunk/drivers/gpu/drm/radeon/atom.c | 9 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 13 - trunk/drivers/gpu/drm/radeon/r600.c | 17 +- trunk/drivers/gpu/drm/radeon/r600_hdmi.c | 1 + trunk/drivers/gpu/drm/radeon/radeon.h | 6 - trunk/drivers/gpu/drm/radeon/radeon_asic.c | 18 - trunk/drivers/gpu/drm/radeon/radeon_asic.h | 7 +- .../gpu/drm/radeon/radeon_atpx_handler.c | 73 +-- trunk/drivers/gpu/drm/radeon/radeon_device.c | 9 +- trunk/drivers/gpu/drm/radeon/radeon_kms.c | 11 +- trunk/drivers/gpu/drm/radeon/radeon_pm.c | 2 +- trunk/drivers/gpu/drm/radeon/rv770.c | 25 - trunk/drivers/gpu/drm/radeon/rv770d.h | 4 - trunk/drivers/gpu/drm/radeon/si.c | 31 +- trunk/drivers/gpu/drm/radeon/sid.h | 5 - trunk/drivers/gpu/stub/Kconfig | 18 + trunk/drivers/gpu/stub/Makefile | 1 + trunk/drivers/gpu/stub/poulsbo.c | 64 +++ trunk/drivers/iommu/intel-iommu.c | 8 +- trunk/drivers/staging/Kconfig | 2 + trunk/drivers/staging/Makefile | 1 + .../{gpu/drm => staging}/omapdrm/Kconfig | 0 .../{gpu/drm => staging}/omapdrm/Makefile | 0 trunk/drivers/staging/omapdrm/TODO | 32 ++ .../drm => staging}/omapdrm/omap_connector.c | 2 +- .../{gpu/drm => staging}/omapdrm/omap_crtc.c | 14 +- .../drm => staging}/omapdrm/omap_debugfs.c | 16 +- .../drm => staging}/omapdrm/omap_dmm_priv.h | 5 - .../drm => staging}/omapdrm/omap_dmm_tiler.c | 159 ++---- .../drm => staging}/omapdrm/omap_dmm_tiler.h | 0 .../staging/omapdrm}/omap_drm.h | 2 +- .../{gpu/drm => staging}/omapdrm/omap_drv.c | 16 +- .../{gpu/drm => staging}/omapdrm/omap_drv.h | 8 +- .../drm => staging}/omapdrm/omap_encoder.c | 2 +- .../{gpu/drm => staging}/omapdrm/omap_fb.c | 2 +- .../{gpu/drm => staging}/omapdrm/omap_fbdev.c | 5 +- .../{gpu/drm => staging}/omapdrm/omap_gem.c | 34 +- .../drm => staging}/omapdrm/omap_gem_dmabuf.c | 8 +- .../omapdrm/omap_gem_helpers.c | 2 +- .../{gpu/drm => staging}/omapdrm/omap_irq.c | 2 +- .../{gpu/drm => staging}/omapdrm/omap_plane.c | 2 +- .../{gpu/drm => staging}/omapdrm/tcm-sita.c | 0 .../{gpu/drm => staging}/omapdrm/tcm-sita.h | 0 .../{gpu/drm => staging}/omapdrm/tcm.h | 2 - trunk/drivers/video/Kconfig | 2 + trunk/include/drm/intel-gtt.h | 3 +- 226 files changed, 3334 insertions(+), 8159 deletions(-) delete mode 100644 trunk/Documentation/thermal/nouveau_thermal delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/core/event.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/engine/disp/base.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/include/core/event.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/include/subdev/bus.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/bios/xpio.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fannil.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.c delete mode 100644 trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/nv10_fence.h delete mode 100644 trunk/drivers/gpu/drm/nouveau/nv17_fence.c delete mode 100644 trunk/drivers/gpu/drm/omapdrm/TODO create mode 100644 trunk/drivers/gpu/stub/Kconfig create mode 100644 trunk/drivers/gpu/stub/Makefile create mode 100644 trunk/drivers/gpu/stub/poulsbo.c rename trunk/drivers/{gpu/drm => staging}/omapdrm/Kconfig (100%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/Makefile (100%) create mode 100644 trunk/drivers/staging/omapdrm/TODO rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_connector.c (99%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_crtc.c (98%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_debugfs.c (90%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_dmm_priv.h (96%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_dmm_tiler.c (86%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_dmm_tiler.h (100%) rename trunk/{include/uapi/drm => drivers/staging/omapdrm}/omap_drm.h (99%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_drv.c (97%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_drv.h (98%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_encoder.c (99%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_fb.c (99%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_fbdev.c (98%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_gem.c (97%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_gem_dmabuf.c (98%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_gem_helpers.c (98%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_irq.c (99%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/omap_plane.c (99%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/tcm-sita.c (100%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/tcm-sita.h (100%) rename trunk/drivers/{gpu/drm => staging}/omapdrm/tcm.h (99%) diff --git a/[refs] b/[refs] index 773f8877bb97..4762e5b391ba 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 74e1697478ffdee0e12e48db024a9b3677fd8cee +refs/heads/master: 50fdaae79abbfc4f04b5380ac5abf00fd448c5a5 diff --git a/trunk/Documentation/thermal/nouveau_thermal b/trunk/Documentation/thermal/nouveau_thermal deleted file mode 100644 index efceb7828f54..000000000000 --- a/trunk/Documentation/thermal/nouveau_thermal +++ /dev/null @@ -1,81 +0,0 @@ -Kernel driver nouveau -=================== - -Supported chips: -* NV43+ - -Authors: Martin Peres (mupuf) - -Description ---------- - -This driver allows to read the GPU core temperature, drive the GPU fan and -set temperature alarms. - -Currently, due to the absence of in-kernel API to access HWMON drivers, Nouveau -cannot access any of the i2c external monitoring chips it may find. If you -have one of those, temperature and/or fan management through Nouveau's HWMON -interface is likely not to work. This document may then not cover your situation -entirely. - -Temperature management --------------------- - -Temperature is exposed under as a read-only HWMON attribute temp1_input. - -In order to protect the GPU from overheating, Nouveau supports 4 configurable -temperature thresholds: - - * Fan_boost: Fan speed is set to 100% when reaching this temperature; - * Downclock: The GPU will be downclocked to reduce its power dissipation; - * Critical: The GPU is put on hold to further lower power dissipation; - * Shutdown: Shut the computer down to protect your GPU. - -WARNING: Some of these thresholds may not be used by Nouveau depending -on your chipset. - -The default value for these thresholds comes from the GPU's vbios. These -thresholds can be configured thanks to the following HWMON attributes: - - * Fan_boost: temp1_auto_point1_temp and temp1_auto_point1_temp_hyst; - * Downclock: temp1_max and temp1_max_hyst; - * Critical: temp1_crit and temp1_crit_hyst; - * Shutdown: temp1_emergency and temp1_emergency_hyst. - -NOTE: Remember that the values are stored as milli degrees Celcius. Don't forget -to multiply! - -Fan management ------------- - -Not all cards have a drivable fan. If you do, then the following HWMON -attributes should be available: - - * pwm1_enable: Current fan management mode (NONE, MANUAL or AUTO); - * pwm1: Current PWM value (power percentage); - * pwm1_min: The minimum PWM speed allowed; - * pwm1_max: The maximum PWM speed allowed (bypassed when hitting Fan_boost); - -You may also have the following attribute: - - * fan1_input: Speed in RPM of your fan. - -Your fan can be driven in different modes: - - * 0: The fan is left untouched; - * 1: The fan can be driven in manual (use pwm1 to change the speed); - * 2; The fan is driven automatically depending on the temperature. - -NOTE: Be sure to use the manual mode if you want to drive the fan speed manually - -NOTE2: Not all fan management modes may be supported on all chipsets. We are -working on it. - -Bug reports ---------- - -Thermal management on Nouveau is new and may not work on all cards. If you have -inquiries, please ping mupuf on IRC (#nouveau, freenode). - -Bug reports should be filled on Freedesktop's bug tracker. Please follow -http://nouveau.freedesktop.org/wiki/Bugs diff --git a/trunk/drivers/char/agp/intel-gtt.c b/trunk/drivers/char/agp/intel-gtt.c index b8e2014cb9cb..d8e7e6c9114e 100644 --- a/trunk/drivers/char/agp/intel-gtt.c +++ b/trunk/drivers/char/agp/intel-gtt.c @@ -572,40 +572,6 @@ static void intel_gtt_cleanup(void) intel_gtt_teardown_scratch_page(); } -/* Certain Gen5 chipsets require require idling the GPU before - * unmapping anything from the GTT when VT-d is enabled. - */ -static inline int needs_ilk_vtd_wa(void) -{ -#ifdef CONFIG_INTEL_IOMMU - const unsigned short gpu_devid = intel_private.pcidev->device; - - /* Query intel_iommu to see if we need the workaround. Presumably that - * was loaded first. - */ - if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || - gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && - intel_iommu_gfx_mapped) - return 1; -#endif - return 0; -} - -static bool intel_gtt_can_wc(void) -{ - if (INTEL_GTT_GEN <= 2) - return false; - - if (INTEL_GTT_GEN >= 6) - return false; - - /* Reports of major corruption with ILK vt'd enabled */ - if (needs_ilk_vtd_wa()) - return false; - - return true; -} - static int intel_gtt_init(void) { u32 gma_addr; @@ -635,7 +601,7 @@ static int intel_gtt_init(void) gtt_map_size = intel_private.gtt_total_entries * 4; intel_private.gtt = NULL; - if (intel_gtt_can_wc()) + if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2) intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr, gtt_map_size); if (intel_private.gtt == NULL) @@ -1106,6 +1072,7 @@ static void i965_write_entry(dma_addr_t addr, writel(addr | pte_flags, intel_private.gtt + entry); } + static int i9xx_setup(void) { u32 reg_addr, gtt_addr; @@ -1404,13 +1371,10 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, } EXPORT_SYMBOL(intel_gmch_probe); -void intel_gtt_get(size_t *gtt_total, size_t *stolen_size, - phys_addr_t *mappable_base, unsigned long *mappable_end) +void intel_gtt_get(size_t *gtt_total, size_t *stolen_size) { *gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT; *stolen_size = intel_private.stolen_size; - *mappable_base = intel_private.gma_bus_addr; - *mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT; } EXPORT_SYMBOL(intel_gtt_get); diff --git a/trunk/drivers/gpu/Makefile b/trunk/drivers/gpu/Makefile index 30879df3daea..cc9277885dd0 100644 --- a/trunk/drivers/gpu/Makefile +++ b/trunk/drivers/gpu/Makefile @@ -1 +1 @@ -obj-y += drm/ vga/ +obj-y += drm/ vga/ stub/ diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index 0ce5f52ac56e..ed9e3af17b31 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -215,5 +215,3 @@ source "drivers/gpu/drm/cirrus/Kconfig" source "drivers/gpu/drm/shmobile/Kconfig" source "drivers/gpu/drm/tegra/Kconfig" - -source "drivers/gpu/drm/omapdrm/Kconfig" diff --git a/trunk/drivers/gpu/drm/Makefile b/trunk/drivers/gpu/drm/Makefile index b6b43cbc18e4..6f58c81cfcbc 100644 --- a/trunk/drivers/gpu/drm/Makefile +++ b/trunk/drivers/gpu/drm/Makefile @@ -50,5 +50,4 @@ obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-$(CONFIG_DRM_TEGRA) += tegra/ -obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-y += i2c/ diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index 781aef524b3b..f17077307c65 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -1996,9 +1996,9 @@ int drm_mode_setplane(struct drm_device *dev, void *data, plane_req->src_w, plane_req->src_h); if (!ret) { old_fb = plane->fb; + fb = NULL; plane->crtc = crtc; plane->fb = fb; - fb = NULL; } drm_modeset_unlock_all(dev); @@ -2267,7 +2267,7 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) switch (bpp) { case 8: - fmt = DRM_FORMAT_C8; + fmt = DRM_FORMAT_RGB332; break; case 16: if (depth == 15) @@ -3870,7 +3870,6 @@ void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp) { switch (format) { - case DRM_FORMAT_C8: case DRM_FORMAT_RGB332: case DRM_FORMAT_BGR233: *depth = 8; diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index 67aa0dd68250..e1aca7b53987 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -2054,8 +2054,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) num_modes += add_cvt_modes(connector, edid); num_modes += add_standard_modes(connector, edid); num_modes += add_established_modes(connector, edid); - if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) - num_modes += add_inferred_modes(connector, edid); + num_modes += add_inferred_modes(connector, edid); num_modes += add_cea_modes(connector, edid); if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) diff --git a/trunk/drivers/gpu/drm/drm_fb_cma_helper.c b/trunk/drivers/gpu/drm/drm_fb_cma_helper.c index 1c8549dae99a..ef68e34b16ec 100644 --- a/trunk/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_cma_helper.c @@ -377,13 +377,12 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_fini); */ void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma) { - if (fbdev_cma) { - struct drm_device *dev = fbdev_cma->fb_helper.dev; + struct drm_device *dev = fbdev_cma->fb_helper.dev; - drm_modeset_lock_all(dev); + drm_modeset_lock_all(dev); + if (fbdev_cma) drm_fb_helper_restore_fbdev_mode(&fbdev_cma->fb_helper); - drm_modeset_unlock_all(dev); - } + drm_modeset_unlock_all(dev); } EXPORT_SYMBOL_GPL(drm_fbdev_cma_restore_mode); diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index 7c65ab83914a..e0e77b89d114 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -694,7 +694,7 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, error->time.tv_usec); - seq_printf(m, "Kernel: " UTS_RELEASE "\n"); + seq_printf(m, "Kernel: " UTS_RELEASE); seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); seq_printf(m, "EIR: 0x%08x\n", error->eir); seq_printf(m, "IER: 0x%08x\n", error->ier); @@ -1484,8 +1484,7 @@ static int i915_context_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; drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - int ret, i; + int ret; ret = mutex_lock_interruptible(&dev->mode_config.mutex); if (ret) @@ -1503,14 +1502,6 @@ static int i915_context_status(struct seq_file *m, void *unused) seq_printf(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_printf(m, "\n"); - } - } - mutex_unlock(&dev->mode_config.mutex); return 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 4fa6beb14c77..cf0610330135 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1610,7 +1610,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mutex_init(&dev_priv->dpio_lock); mutex_init(&dev_priv->rps.hw_lock); - mutex_init(&dev_priv->modeset_restore_lock); if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) dev_priv->num_pipe = 3; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index c5b8c81b9440..d159d7a402e9 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -470,11 +470,6 @@ static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - /* ignore lid events during suspend */ - mutex_lock(&dev_priv->modeset_restore_lock); - dev_priv->modeset_restore = MODESET_SUSPENDED; - mutex_unlock(&dev_priv->modeset_restore_lock); - intel_set_power_well(dev, true); drm_kms_helper_poll_disable(dev); @@ -501,6 +496,9 @@ static int i915_drm_freeze(struct drm_device *dev) intel_opregion_fini(dev); + /* Modeset on resume, not lid events */ + dev_priv->modeset_on_lid = 0; + console_lock(); intel_fbdev_set_suspend(dev, 1); console_unlock(); @@ -576,6 +574,8 @@ static int __i915_drm_thaw(struct drm_device *dev) intel_opregion_init(dev); + dev_priv->modeset_on_lid = 0; + /* * The console lock can be pretty contented on resume due * to all the printk activity. Try to keep it out of the hot @@ -588,9 +588,6 @@ static int __i915_drm_thaw(struct drm_device *dev) schedule_work(&dev_priv->console_resume_work); } - mutex_lock(&dev_priv->modeset_restore_lock); - dev_priv->modeset_restore = MODESET_DONE; - mutex_unlock(&dev_priv->modeset_restore_lock); return error; } diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index e95337c97459..c338b4443fd9 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -399,8 +399,7 @@ struct i915_gtt { /* global gtt ops */ int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total, - size_t *stolen, phys_addr_t *mappable_base, - unsigned long *mappable_end); + size_t *stolen); void (*gtt_remove)(struct drm_device *dev); void (*gtt_clear_range)(struct drm_device *dev, unsigned int first_entry, @@ -847,12 +846,6 @@ struct i915_gpu_error { unsigned int stop_rings; }; -enum modeset_restore { - MODESET_ON_LID_OPEN, - MODESET_DONE, - MODESET_SUSPENDED, -}; - typedef struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -926,7 +919,7 @@ typedef struct drm_i915_private { /* overlay */ struct intel_overlay *overlay; - unsigned int sprite_scaling_enabled; + bool sprite_scaling_enabled; /* LVDS info */ int backlight_level; /* restore backlight to this value */ @@ -974,8 +967,8 @@ typedef struct drm_i915_private { unsigned long quirks; - enum modeset_restore modeset_restore; - struct mutex modeset_restore_lock; + /* Register state */ + bool modeset_on_lid; struct i915_gtt gtt; @@ -1040,7 +1033,7 @@ typedef struct drm_i915_private { bool hw_contexts_disabled; uint32_t hw_context_size; - u32 fdi_rx_config; + bool fdi_rx_polarity_reversed; struct i915_suspend_saved_registers regfile; @@ -1215,6 +1208,13 @@ struct drm_i915_gem_object { /** for phy allocated objects */ struct drm_i915_gem_phys_object *phys_obj; + + /** + * Number of crtcs where this object is currently the fb, but + * will be page flipped away on the next vblank. When it + * reaches 0, dev_priv->pending_flip_queue will be woken up. + */ + atomic_t pending_flip; }; #define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 8413ffced815..62be74899c2b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -3021,13 +3021,6 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj) if (obj->pages == NULL) return; - /* - * Stolen memory is always coherent with the GPU as it is explicitly - * marked as wc by the system, or the system is cache-coherent. - */ - if (obj->stolen) - return; - /* If the GPU is snooping the contents of the CPU cache, * we do not need to manually clear the CPU cache lines. However, * the caches are only snooped when the render cache is @@ -3872,7 +3865,7 @@ void i915_gem_l3_remap(struct drm_device *dev) u32 misccpctl; int i; - if (!HAS_L3_GPU_CACHE(dev)) + if (!IS_IVYBRIDGE(dev)) return; if (!dev_priv->l3_parity.remap_info) @@ -3937,11 +3930,22 @@ intel_enable_blt(struct drm_device *dev) return true; } -static int i915_gem_init_rings(struct drm_device *dev) +int +i915_gem_init_hw(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = dev->dev_private; int ret; + if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) + return -EIO; + + if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) + I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); + + i915_gem_l3_remap(dev); + + i915_gem_init_swizzling(dev); + ret = intel_init_render_ring_buffer(dev); if (ret) return ret; @@ -3959,38 +3963,6 @@ static int i915_gem_init_rings(struct drm_device *dev) } ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000)); - if (ret) - goto cleanup_blt_ring; - - return 0; - -cleanup_blt_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[BCS]); -cleanup_bsd_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[VCS]); -cleanup_render_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[RCS]); - - return ret; -} - -int -i915_gem_init_hw(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) - return -EIO; - - if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) - I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); - - i915_gem_l3_remap(dev); - - i915_gem_init_swizzling(dev); - - ret = i915_gem_init_rings(dev); if (ret) return ret; @@ -4002,6 +3974,12 @@ i915_gem_init_hw(struct drm_device *dev) i915_gem_init_ppgtt(dev); return 0; + +cleanup_bsd_ring: + intel_cleanup_ring_buffer(&dev_priv->ring[VCS]); +cleanup_render_ring: + intel_cleanup_ring_buffer(&dev_priv->ring[RCS]); + return ret; } int i915_gem_init(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_context.c b/trunk/drivers/gpu/drm/i915/i915_gem_context.c index 21177d9df423..a3f06bcad551 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_context.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_context.c @@ -126,8 +126,13 @@ static int get_context_size(struct drm_device *dev) static void do_destroy(struct i915_hw_context *ctx) { + struct drm_device *dev = ctx->obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + if (ctx->file_priv) idr_remove(&ctx->file_priv->context_idr, ctx->id); + else + BUG_ON(ctx != dev_priv->ring[RCS].default_context); drm_gem_object_unreference(&ctx->obj->base); kfree(ctx); @@ -237,6 +242,7 @@ static int create_default_context(struct drm_i915_private *dev_priv) void i915_gem_context_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t ctx_size; if (!HAS_HW_CONTEXTS(dev)) { dev_priv->hw_contexts_disabled = true; @@ -248,9 +254,11 @@ void i915_gem_context_init(struct drm_device *dev) dev_priv->ring[RCS].default_context) return; - dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); + ctx_size = get_context_size(dev); + dev_priv->hw_context_size = get_context_size(dev); + dev_priv->hw_context_size = round_up(dev_priv->hw_context_size, 4096); - if (dev_priv->hw_context_size > (1<<20)) { + if (ctx_size <= 0 || ctx_size > (1<<20)) { dev_priv->hw_contexts_disabled = true; return; } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c index 926a1e2dd234..bdaca3f47988 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -725,9 +725,7 @@ static inline size_t gen7_get_stolen_size(u16 snb_gmch_ctl) static int gen6_gmch_probe(struct drm_device *dev, size_t *gtt_total, - size_t *stolen, - phys_addr_t *mappable_base, - unsigned long *mappable_end) + size_t *stolen) { struct drm_i915_private *dev_priv = dev->dev_private; phys_addr_t gtt_bus_addr; @@ -735,13 +733,11 @@ static int gen6_gmch_probe(struct drm_device *dev, u16 snb_gmch_ctl; int ret; - *mappable_base = pci_resource_start(dev->pdev, 2); - *mappable_end = pci_resource_len(dev->pdev, 2); - /* 64/512MB is the current min/max we actually know of, but this is just * a coarse sanity check. */ - if ((*mappable_end < (64<<20) || (*mappable_end > (512<<20)))) { + if ((dev_priv->gtt.mappable_end < (64<<20) || + (dev_priv->gtt.mappable_end > (512<<20)))) { DRM_ERROR("Unknown GMADR size (%lx)\n", dev_priv->gtt.mappable_end); return -ENXIO; @@ -786,9 +782,7 @@ static void gen6_gmch_remove(struct drm_device *dev) static int i915_gmch_probe(struct drm_device *dev, size_t *gtt_total, - size_t *stolen, - phys_addr_t *mappable_base, - unsigned long *mappable_end) + size_t *stolen) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -799,7 +793,7 @@ static int i915_gmch_probe(struct drm_device *dev, return -EIO; } - intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end); + intel_gtt_get(gtt_total, stolen); dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev); dev_priv->gtt.gtt_clear_range = i915_ggtt_clear_range; @@ -820,6 +814,9 @@ int i915_gem_gtt_init(struct drm_device *dev) unsigned long gtt_size; int ret; + gtt->mappable_base = pci_resource_start(dev->pdev, 2); + gtt->mappable_end = pci_resource_len(dev->pdev, 2); + if (INTEL_INFO(dev)->gen <= 5) { dev_priv->gtt.gtt_probe = i915_gmch_probe; dev_priv->gtt.gtt_remove = i915_gmch_remove; @@ -829,9 +826,7 @@ int i915_gem_gtt_init(struct drm_device *dev) } ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total, - &dev_priv->gtt.stolen_size, - >t->mappable_base, - >t->mappable_end); + &dev_priv->gtt.stolen_size); if (ret) return ret; diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 2cd97d1cc920..13bb8d3f2a77 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -1924,7 +1924,7 @@ static void valleyview_irq_preinstall(struct drm_device *dev) * This register is the same on all known PCH chips. */ -static void ibx_enable_hotplug(struct drm_device *dev) +static void ironlake_enable_pch_hotplug(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u32 hotplug; @@ -1937,28 +1937,6 @@ static void ibx_enable_hotplug(struct drm_device *dev) I915_WRITE(PCH_PORT_HOTPLUG, hotplug); } -static void ibx_irq_postinstall(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 mask; - - if (HAS_PCH_IBX(dev)) - mask = SDE_HOTPLUG_MASK | - SDE_GMBUS | - SDE_AUX_MASK; - else - mask = SDE_HOTPLUG_MASK_CPT | - SDE_GMBUS_CPT | - SDE_AUX_MASK_CPT; - - I915_WRITE(SDEIIR, I915_READ(SDEIIR)); - I915_WRITE(SDEIMR, ~mask); - I915_WRITE(SDEIER, mask); - POSTING_READ(SDEIER); - - ibx_enable_hotplug(dev); -} - static int ironlake_irq_postinstall(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -1967,6 +1945,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev) DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | DE_AUX_CHANNEL_A; u32 render_irqs; + u32 hotplug_mask; + u32 pch_irq_mask; dev_priv->irq_mask = ~display_mask; @@ -1994,7 +1974,30 @@ static int ironlake_irq_postinstall(struct drm_device *dev) I915_WRITE(GTIER, render_irqs); POSTING_READ(GTIER); - ibx_irq_postinstall(dev); + if (HAS_PCH_CPT(dev)) { + hotplug_mask = (SDE_CRT_HOTPLUG_CPT | + SDE_PORTB_HOTPLUG_CPT | + SDE_PORTC_HOTPLUG_CPT | + SDE_PORTD_HOTPLUG_CPT | + SDE_GMBUS_CPT | + SDE_AUX_MASK_CPT); + } else { + hotplug_mask = (SDE_CRT_HOTPLUG | + SDE_PORTB_HOTPLUG | + SDE_PORTC_HOTPLUG | + SDE_PORTD_HOTPLUG | + SDE_GMBUS | + SDE_AUX_MASK); + } + + pch_irq_mask = ~hotplug_mask; + + I915_WRITE(SDEIIR, I915_READ(SDEIIR)); + I915_WRITE(SDEIMR, pch_irq_mask); + I915_WRITE(SDEIER, hotplug_mask); + POSTING_READ(SDEIER); + + ironlake_enable_pch_hotplug(dev); if (IS_IRONLAKE_M(dev)) { /* Clear & enable PCU event interrupts */ @@ -2017,6 +2020,8 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB; u32 render_irqs; + u32 hotplug_mask; + u32 pch_irq_mask; dev_priv->irq_mask = ~display_mask; @@ -2040,7 +2045,20 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) I915_WRITE(GTIER, render_irqs); POSTING_READ(GTIER); - ibx_irq_postinstall(dev); + hotplug_mask = (SDE_CRT_HOTPLUG_CPT | + SDE_PORTB_HOTPLUG_CPT | + SDE_PORTC_HOTPLUG_CPT | + SDE_PORTD_HOTPLUG_CPT | + SDE_GMBUS_CPT | + SDE_AUX_MASK_CPT); + pch_irq_mask = ~hotplug_mask; + + I915_WRITE(SDEIIR, I915_READ(SDEIIR)); + I915_WRITE(SDEIMR, pch_irq_mask); + I915_WRITE(SDEIER, hotplug_mask); + POSTING_READ(SDEIER); + + ironlake_enable_pch_hotplug(dev); return 0; } @@ -2119,12 +2137,12 @@ static void valleyview_hpd_irq_setup(struct drm_device *dev) u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); /* Note HDMI and DP share bits */ - if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) - hotplug_en |= PORTB_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) - hotplug_en |= PORTC_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) - hotplug_en |= PORTD_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIB_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIC_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) + hotplug_en |= HDMID_HOTPLUG_INT_EN; if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915) hotplug_en |= SDVOC_HOTPLUG_INT_EN; if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915) @@ -2390,12 +2408,12 @@ static void i915_hpd_irq_setup(struct drm_device *dev) if (I915_HAS_HOTPLUG(dev)) { hotplug_en = I915_READ(PORT_HOTPLUG_EN); - if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) - hotplug_en |= PORTB_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) - hotplug_en |= PORTC_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) - hotplug_en |= PORTD_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIB_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIC_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) + hotplug_en |= HDMID_HOTPLUG_INT_EN; if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915) hotplug_en |= SDVOC_HOTPLUG_INT_EN; if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915) @@ -2624,12 +2642,12 @@ static void i965_hpd_irq_setup(struct drm_device *dev) /* Note HDMI and DP share hotplug bits */ hotplug_en = 0; - if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) - hotplug_en |= PORTB_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) - hotplug_en |= PORTC_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) - hotplug_en |= PORTD_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIB_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIC_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) + hotplug_en |= HDMID_HOTPLUG_INT_EN; if (IS_G4X(dev)) { if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X) hotplug_en |= SDVOC_HOTPLUG_INT_EN; diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 527b664d3434..15f5e7f9cded 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -308,7 +308,6 @@ #define DISPLAY_PLANE_A (0<<20) #define DISPLAY_PLANE_B (1<<20) #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) -#define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */ #define PIPE_CONTROL_CS_STALL (1<<20) #define PIPE_CONTROL_TLB_INVALIDATE (1<<18) #define PIPE_CONTROL_QW_WRITE (1<<14) @@ -1236,10 +1235,6 @@ #define MAD_DIMM_A_SIZE_SHIFT 0 #define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT) -/** snb MCH registers for priority tuning */ -#define MCH_SSKPD (MCHBAR_MIRROR_BASE_SNB + 0x5d10) -#define MCH_SSKPD_WM0_MASK 0x3f -#define MCH_SSKPD_WM0_VAL 0xc /* Clocking configuration register */ #define CLKCFG 0x10c00 @@ -1630,9 +1625,12 @@ /* Hotplug control (945+ only) */ #define PORT_HOTPLUG_EN (dev_priv->info->display_mmio_offset + 0x61110) -#define PORTB_HOTPLUG_INT_EN (1 << 29) -#define PORTC_HOTPLUG_INT_EN (1 << 28) -#define PORTD_HOTPLUG_INT_EN (1 << 27) +#define HDMIB_HOTPLUG_INT_EN (1 << 29) +#define DPB_HOTPLUG_INT_EN (1 << 29) +#define HDMIC_HOTPLUG_INT_EN (1 << 28) +#define DPC_HOTPLUG_INT_EN (1 << 28) +#define HDMID_HOTPLUG_INT_EN (1 << 27) +#define DPD_HOTPLUG_INT_EN (1 << 27) #define SDVOB_HOTPLUG_INT_EN (1 << 26) #define SDVOC_HOTPLUG_INT_EN (1 << 25) #define TV_HOTPLUG_INT_EN (1 << 18) @@ -1655,12 +1653,19 @@ #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) /* HDMI/DP bits are gen4+ */ -#define PORTB_HOTPLUG_LIVE_STATUS (1 << 29) -#define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) -#define PORTD_HOTPLUG_LIVE_STATUS (1 << 27) -#define PORTD_HOTPLUG_INT_STATUS (3 << 21) -#define PORTC_HOTPLUG_INT_STATUS (3 << 19) -#define PORTB_HOTPLUG_INT_STATUS (3 << 17) +#define DPB_HOTPLUG_LIVE_STATUS (1 << 29) +#define DPC_HOTPLUG_LIVE_STATUS (1 << 28) +#define DPD_HOTPLUG_LIVE_STATUS (1 << 27) +#define DPD_HOTPLUG_INT_STATUS (3 << 21) +#define DPC_HOTPLUG_INT_STATUS (3 << 19) +#define DPB_HOTPLUG_INT_STATUS (3 << 17) +/* HDMI bits are shared with the DP bits */ +#define HDMIB_HOTPLUG_LIVE_STATUS (1 << 29) +#define HDMIC_HOTPLUG_LIVE_STATUS (1 << 28) +#define HDMID_HOTPLUG_LIVE_STATUS (1 << 27) +#define HDMID_HOTPLUG_INT_STATUS (3 << 21) +#define HDMIC_HOTPLUG_INT_STATUS (3 << 19) +#define HDMIB_HOTPLUG_INT_STATUS (3 << 17) /* CRT/TV common between gen3+ */ #define CRT_HOTPLUG_INT_STATUS (1 << 11) #define TV_HOTPLUG_INT_STATUS (1 << 10) @@ -2949,7 +2954,6 @@ #define CURSOR_ENABLE 0x80000000 #define CURSOR_GAMMA_ENABLE 0x40000000 #define CURSOR_STRIDE_MASK 0x30000000 -#define CURSOR_PIPE_CSC_ENABLE (1<<24) #define CURSOR_FORMAT_SHIFT 24 #define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) #define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) @@ -3011,7 +3015,6 @@ #define DISPPLANE_RGBA888 (0xf<<26) #define DISPPLANE_STEREO_ENABLE (1<<25) #define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_PIPE_CSC_ENABLE (1<<24) #define DISPPLANE_SEL_PIPE_SHIFT 24 #define DISPPLANE_SEL_PIPE_MASK (3< 0 ? ((vids) * 5) + 245 : 0) #define GEN6_PCODE_DATA 0x138128 #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 @@ -4514,7 +4516,6 @@ #define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */ #define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */ #define DDI_BUF_EMP_MASK (0xf<<24) -#define DDI_BUF_PORT_REVERSAL (1<<16) #define DDI_BUF_IS_IDLE (1<<7) #define DDI_A_4_LANES (1<<4) #define DDI_PORT_WIDTH_X1 (0<<1) @@ -4648,51 +4649,4 @@ #define WM_DBG_DISALLOW_MAXFIFO (1<<1) #define WM_DBG_DISALLOW_SPRITE (1<<2) -/* pipe CSC */ -#define _PIPE_A_CSC_COEFF_RY_GY 0x49010 -#define _PIPE_A_CSC_COEFF_BY 0x49014 -#define _PIPE_A_CSC_COEFF_RU_GU 0x49018 -#define _PIPE_A_CSC_COEFF_BU 0x4901c -#define _PIPE_A_CSC_COEFF_RV_GV 0x49020 -#define _PIPE_A_CSC_COEFF_BV 0x49024 -#define _PIPE_A_CSC_MODE 0x49028 -#define _PIPE_A_CSC_PREOFF_HI 0x49030 -#define _PIPE_A_CSC_PREOFF_ME 0x49034 -#define _PIPE_A_CSC_PREOFF_LO 0x49038 -#define _PIPE_A_CSC_POSTOFF_HI 0x49040 -#define _PIPE_A_CSC_POSTOFF_ME 0x49044 -#define _PIPE_A_CSC_POSTOFF_LO 0x49048 - -#define _PIPE_B_CSC_COEFF_RY_GY 0x49110 -#define _PIPE_B_CSC_COEFF_BY 0x49114 -#define _PIPE_B_CSC_COEFF_RU_GU 0x49118 -#define _PIPE_B_CSC_COEFF_BU 0x4911c -#define _PIPE_B_CSC_COEFF_RV_GV 0x49120 -#define _PIPE_B_CSC_COEFF_BV 0x49124 -#define _PIPE_B_CSC_MODE 0x49128 -#define _PIPE_B_CSC_PREOFF_HI 0x49130 -#define _PIPE_B_CSC_PREOFF_ME 0x49134 -#define _PIPE_B_CSC_PREOFF_LO 0x49138 -#define _PIPE_B_CSC_POSTOFF_HI 0x49140 -#define _PIPE_B_CSC_POSTOFF_ME 0x49144 -#define _PIPE_B_CSC_POSTOFF_LO 0x49148 - -#define CSC_BLACK_SCREEN_OFFSET (1 << 2) -#define CSC_POSITION_BEFORE_GAMMA (1 << 1) -#define CSC_MODE_YUV_TO_RGB (1 << 0) - -#define PIPE_CSC_COEFF_RY_GY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY) -#define PIPE_CSC_COEFF_BY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY) -#define PIPE_CSC_COEFF_RU_GU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU) -#define PIPE_CSC_COEFF_BU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BU, _PIPE_B_CSC_COEFF_BU) -#define PIPE_CSC_COEFF_RV_GV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RV_GV, _PIPE_B_CSC_COEFF_RV_GV) -#define PIPE_CSC_COEFF_BV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BV, _PIPE_B_CSC_COEFF_BV) -#define PIPE_CSC_MODE(pipe) _PIPE(pipe, _PIPE_A_CSC_MODE, _PIPE_B_CSC_MODE) -#define PIPE_CSC_PREOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_HI, _PIPE_B_CSC_PREOFF_HI) -#define PIPE_CSC_PREOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_ME, _PIPE_B_CSC_PREOFF_ME) -#define PIPE_CSC_PREOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_LO, _PIPE_B_CSC_PREOFF_LO) -#define PIPE_CSC_POSTOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_HI, _PIPE_B_CSC_POSTOFF_HI) -#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) - #endif /* _I915_REG_H_ */ diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 969d08c72d10..729dd1a3fe72 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -800,14 +800,10 @@ void intel_crt_init(struct drm_device *dev) dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; /* - * TODO: find a proper way to discover whether we need to set the the - * polarity and link reversal bits or not, instead of relying on the - * BIOS. + * TODO: find a proper way to discover whether we need to set the + * polarity reversal bit or not, instead of relying on the BIOS. */ - if (HAS_PCH_LPT(dev)) { - u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT | - FDI_RX_LINK_REVERSAL_OVERRIDE; - - dev_priv->fdi_rx_config = I915_READ(_FDI_RXA_CTL) & fdi_config; - } + if (HAS_PCH_LPT(dev)) + dev_priv->fdi_rx_polarity_reversed = + !!(I915_READ(_FDI_RXA_CTL) & FDI_RX_POLARITY_REVERSED_LPT); } diff --git a/trunk/drivers/gpu/drm/i915/intel_ddi.c b/trunk/drivers/gpu/drm/i915/intel_ddi.c index d64af5aa4a1c..a259e09eb6a8 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ddi.c +++ b/trunk/drivers/gpu/drm/i915/intel_ddi.c @@ -180,8 +180,10 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); /* Enable the PCH Receiver FDI PLL */ - rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | - FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19); + rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE | + ((intel_crtc->fdi_lanes - 1) << 19); + if (dev_priv->fdi_rx_polarity_reversed) + rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT; I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); POSTING_READ(_FDI_RXA_CTL); udelay(220); @@ -203,10 +205,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_ENABLE); - /* Configure and enable DDI_BUF_CTL for DDI E with next voltage. - * DDI E does not support port reversal, the functionality is - * achieved on the PCH side in FDI_RX_CTL, so no need to set the - * port reversal bit */ + /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */ I915_WRITE(DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 1) | @@ -681,11 +680,8 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder, intel_crtc->eld_vld = false; if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_digital_port *intel_dig_port = - enc_to_dig_port(encoder); - intel_dp->DP = intel_dig_port->port_reversal | - DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; + intel_dp->DP = DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; switch (intel_dp->lane_count) { case 1: intel_dp->DP |= DDI_PORT_WIDTH_X1; @@ -1308,15 +1304,11 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) uint32_t tmp; if (type == INTEL_OUTPUT_HDMI) { - struct intel_digital_port *intel_dig_port = - enc_to_dig_port(encoder); - /* In HDMI/DVI mode, the port width, and swing/emphasis values * are ignored so nothing special needs to be done besides * enabling the port. */ - I915_WRITE(DDI_BUF_CTL(port), - intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE); + I915_WRITE(DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE); } else if (type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -1493,7 +1485,6 @@ static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = { void intel_ddi_init(struct drm_device *dev, enum port port) { - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_digital_port *intel_dig_port; struct intel_encoder *intel_encoder; struct drm_encoder *encoder; @@ -1534,8 +1525,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port) intel_encoder->get_hw_state = intel_ddi_get_hw_state; intel_dig_port->port = port; - intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & - DDI_BUF_PORT_REVERSAL; if (hdmi_connector) intel_dig_port->hdmi.sdvox_reg = DDI_BUF_CTL(port); else diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 6337196b7931..ca8d5929063e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -154,8 +154,8 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { .vco = { .min = 1400000, .max = 2800000 }, .n = { .min = 1, .max = 6 }, .m = { .min = 70, .max = 120 }, - .m1 = { .min = 8, .max = 18 }, - .m2 = { .min = 3, .max = 7 }, + .m1 = { .min = 10, .max = 22 }, + .m2 = { .min = 5, .max = 9 }, .p = { .min = 5, .max = 80 }, .p1 = { .min = 1, .max = 8 }, .p2 = { .dot_limit = 200000, @@ -168,8 +168,8 @@ static const intel_limit_t intel_limits_i9xx_lvds = { .vco = { .min = 1400000, .max = 2800000 }, .n = { .min = 1, .max = 6 }, .m = { .min = 70, .max = 120 }, - .m1 = { .min = 8, .max = 18 }, - .m2 = { .min = 3, .max = 7 }, + .m1 = { .min = 10, .max = 22 }, + .m2 = { .min = 5, .max = 9 }, .p = { .min = 7, .max = 98 }, .p1 = { .min = 1, .max = 8 }, .p2 = { .dot_limit = 112000, @@ -2226,6 +2226,12 @@ intel_finish_fb(struct drm_framebuffer *old_fb) bool was_interruptible = dev_priv->mm.interruptible; int ret; + WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue)); + + wait_event(dev_priv->pending_flip_queue, + i915_reset_in_progress(&dev_priv->gpu_error) || + atomic_read(&obj->pending_flip) == 0); + /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the * current scanout is retired before unpinning the old @@ -2868,12 +2874,10 @@ static bool intel_crtc_has_pending_flip(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); unsigned long flags; bool pending; - if (i915_reset_in_progress(&dev_priv->gpu_error) || - intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) + if (i915_reset_in_progress(&dev_priv->gpu_error)) return false; spin_lock_irqsave(&dev->event_lock, flags); @@ -3611,11 +3615,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_update_watermarks(dev); intel_enable_pll(dev_priv, pipe); - - for_each_encoder_on_crtc(dev, crtc, encoder) - if (encoder->pre_enable) - encoder->pre_enable(encoder); - intel_enable_pipe(dev_priv, pipe, false); intel_enable_plane(dev_priv, plane, pipe); @@ -3638,7 +3637,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) struct intel_encoder *encoder; int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; - u32 pctl; if (!intel_crtc->active) @@ -3658,13 +3656,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) intel_disable_plane(dev_priv, plane, pipe); intel_disable_pipe(dev_priv, pipe); - - /* Disable pannel fitter if it is on this pipe. */ - pctl = I915_READ(PFIT_CONTROL); - if ((pctl & PFIT_ENABLE) && - ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe) - I915_WRITE(PFIT_CONTROL, 0); - intel_disable_pll(dev_priv, pipe); intel_crtc->active = false; @@ -5118,71 +5109,6 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc, POSTING_READ(PIPECONF(pipe)); } -/* - * Set up the pipe CSC unit. - * - * Currently only full range RGB to limited range RGB conversion - * is supported, but eventually this should handle various - * RGB<->YCbCr scenarios as well. - */ -static void intel_set_pipe_csc(struct drm_crtc *crtc, - const struct drm_display_mode *adjusted_mode) -{ - 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; - uint16_t coeff = 0x7800; /* 1.0 */ - - /* - * TODO: Check what kind of values actually come out of the pipe - * with these coeff/postoff values and adjust to get the best - * accuracy. Perhaps we even need to take the bpc value into - * consideration. - */ - - if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) - coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */ - - /* - * GY/GU and RY/RU should be the other way around according - * to BSpec, but reality doesn't agree. Just set them up in - * a way that results in the correct picture. - */ - I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16); - I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0); - - I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff); - I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0); - - I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0); - I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16); - - I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0); - I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0); - I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0); - - if (INTEL_INFO(dev)->gen > 6) { - uint16_t postoff = 0; - - if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) - postoff = (16 * (1 << 13) / 255) & 0x1fff; - - I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff); - I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff); - I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff); - - I915_WRITE(PIPE_CSC_MODE(pipe), 0); - } else { - uint32_t mode = CSC_MODE_YUV_TO_RGB; - - if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) - mode |= CSC_BLACK_SCREEN_OFFSET; - - I915_WRITE(PIPE_CSC_MODE(pipe), mode); - } -} - static void haswell_set_pipeconf(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode, bool dither) @@ -5771,10 +5697,8 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, haswell_set_pipeconf(crtc, adjusted_mode, dither); - intel_set_pipe_csc(crtc, adjusted_mode); - /* Set up the display plane register */ - I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE | DISPPLANE_PIPE_CSC_ENABLE); + I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE); POSTING_READ(DSPCNTR(plane)); ret = intel_pipe_set_base(crtc, x, y, fb); @@ -6179,8 +6103,6 @@ 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)) - cntl |= CURSOR_PIPE_CSC_ENABLE; I915_WRITE(CURCNTR_IVB(pipe), cntl); intel_crtc->cursor_visible = visible; @@ -7313,7 +7235,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->enable_stall_check = true; atomic_inc(&intel_crtc->unpin_work_count); - intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); if (ret) @@ -7955,7 +7876,7 @@ intel_modeset_stage_output_state(struct drm_device *dev, struct intel_encoder *encoder; int count, ro; - /* The upper layers ensure that we either disable a crtc or have a list + /* The upper layers ensure that we either disabl a crtc or have a list * of connectors. For paranoia, double-check this. */ WARN_ON(!set->fb && (set->num_connectors != 0)); WARN_ON(set->fb && (set->num_connectors == 0)); @@ -8734,9 +8655,6 @@ static struct intel_quirk intel_quirks[] = { /* Acer/Packard Bell NCL20 */ { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness }, - - /* Acer Aspire 4736Z */ - { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, }; static void intel_init_quirks(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 31c0205685ab..13c1536a8bb2 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -2302,13 +2302,13 @@ g4x_dp_detect(struct intel_dp *intel_dp) switch (intel_dig_port->port) { case PORT_B: - bit = PORTB_HOTPLUG_LIVE_STATUS; + bit = DPB_HOTPLUG_LIVE_STATUS; break; case PORT_C: - bit = PORTC_HOTPLUG_LIVE_STATUS; + bit = DPC_HOTPLUG_LIVE_STATUS; break; case PORT_D: - bit = PORTD_HOTPLUG_LIVE_STATUS; + bit = DPD_HOTPLUG_LIVE_STATUS; break; default: return connector_status_unknown; @@ -2837,15 +2837,15 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, name = "DPDDC-A"; break; case PORT_B: - dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS; + dev_priv->hotplug_supported_mask |= DPB_HOTPLUG_INT_STATUS; name = "DPDDC-B"; break; case PORT_C: - dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS; + dev_priv->hotplug_supported_mask |= DPC_HOTPLUG_INT_STATUS; name = "DPDDC-C"; break; case PORT_D: - dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS; + dev_priv->hotplug_supported_mask |= DPD_HOTPLUG_INT_STATUS; name = "DPDDC-D"; break; default: diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index d282052aadd4..a2ec01c49f40 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -235,9 +235,6 @@ struct intel_crtc { /* We can share PLLs across outputs if the timings match */ struct intel_pch_pll *pch_pll; uint32_t ddi_pll_sel; - - /* reset counter value when the last flip was submitted */ - unsigned int reset_counter; }; struct intel_plane { @@ -393,7 +390,6 @@ struct intel_dp { struct intel_digital_port { struct intel_encoder base; enum port port; - u32 port_reversal; struct intel_dp dp; struct intel_hdmi hdmi; }; diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 3ea0c8b6a00f..3883bed80faa 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -802,10 +802,10 @@ static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi) switch (intel_dig_port->port) { case PORT_B: - bit = PORTB_HOTPLUG_LIVE_STATUS; + bit = HDMIB_HOTPLUG_LIVE_STATUS; break; case PORT_C: - bit = PORTC_HOTPLUG_LIVE_STATUS; + bit = HDMIC_HOTPLUG_LIVE_STATUS; break; default: bit = 0; @@ -1021,15 +1021,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, switch (port) { case PORT_B: intel_hdmi->ddc_bus = GMBUS_PORT_DPB; - dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS; + dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; break; case PORT_C: intel_hdmi->ddc_bus = GMBUS_PORT_DPC; - dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS; + dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; break; case PORT_D: intel_hdmi->ddc_bus = GMBUS_PORT_DPD; - dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS; + dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; break; case PORT_A: /* Internal port only for eDP. */ diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 3d1d97488cc9..feb43fd7debf 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -51,6 +51,7 @@ struct intel_lvds_encoder { u32 pfit_control; u32 pfit_pgm_ratios; + bool pfit_dirty; bool is_dual_link; u32 reg; @@ -150,29 +151,6 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) I915_WRITE(lvds_encoder->reg, temp); } -static void intel_pre_enable_lvds(struct intel_encoder *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct intel_lvds_encoder *enc = to_lvds_encoder(&encoder->base); - struct drm_i915_private *dev_priv = dev->dev_private; - - if (HAS_PCH_SPLIT(dev) || !enc->pfit_control) - return; - - /* - * Enable automatic panel scaling so that non-native modes - * fill the screen. The panel fitter should only be - * adjusted whilst the pipe is disabled, according to - * register description and PRM. - */ - DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", - enc->pfit_control, - enc->pfit_pgm_ratios); - - I915_WRITE(PFIT_PGM_RATIOS, enc->pfit_pgm_ratios); - I915_WRITE(PFIT_CONTROL, enc->pfit_control); -} - /** * Sets the power state for the panel. */ @@ -194,6 +172,22 @@ static void intel_enable_lvds(struct intel_encoder *encoder) I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN); + if (lvds_encoder->pfit_dirty) { + /* + * Enable automatic panel scaling so that non-native modes + * fill the screen. The panel fitter should only be + * adjusted whilst the pipe is disabled, according to + * register description and PRM. + */ + DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", + lvds_encoder->pfit_control, + lvds_encoder->pfit_pgm_ratios); + + I915_WRITE(PFIT_PGM_RATIOS, lvds_encoder->pfit_pgm_ratios); + I915_WRITE(PFIT_CONTROL, lvds_encoder->pfit_control); + lvds_encoder->pfit_dirty = false; + } + I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); POSTING_READ(lvds_encoder->reg); if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) @@ -223,6 +217,11 @@ static void intel_disable_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 off\n"); + if (lvds_encoder->pfit_control) { + I915_WRITE(PFIT_CONTROL, 0); + lvds_encoder->pfit_dirty = true; + } + I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN); POSTING_READ(lvds_encoder->reg); } @@ -462,6 +461,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) { lvds_encoder->pfit_control = pfit_control; lvds_encoder->pfit_pgm_ratios = pfit_pgm_ratios; + lvds_encoder->pfit_dirty = true; } dev_priv->lvds_border_bits = border; @@ -547,14 +547,13 @@ static const struct dmi_system_id intel_no_modeset_on_lid[] = { }; /* - * Lid events. Note the use of 'modeset': - * - we set it to MODESET_ON_LID_OPEN on lid close, - * and set it to MODESET_DONE on open + * Lid events. Note the use of 'modeset_on_lid': + * - we set it on lid close, and reset it on open * - we use it as a "only once" bit (ie we ignore - * duplicate events where it was already properly set) - * - the suspend/resume paths will set it to - * MODESET_SUSPENDED and ignore the lid open event, - * because they restore the mode ("lid open"). + * duplicate events where it was already properly + * set/reset) + * - the suspend/resume paths will also set it to + * zero, since they restore the mode ("lid open"). */ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, void *unused) @@ -568,9 +567,6 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, if (dev->switch_power_state != DRM_SWITCH_POWER_ON) return NOTIFY_OK; - mutex_lock(&dev_priv->modeset_restore_lock); - if (dev_priv->modeset_restore == MODESET_SUSPENDED) - goto exit; /* * check and update the status of LVDS connector after receiving * the LID nofication event. @@ -579,24 +575,21 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, /* Don't force modeset on machines where it causes a GPU lockup */ if (dmi_check_system(intel_no_modeset_on_lid)) - goto exit; + return NOTIFY_OK; if (!acpi_lid_open()) { - /* do modeset on next lid open event */ - dev_priv->modeset_restore = MODESET_ON_LID_OPEN; - goto exit; + dev_priv->modeset_on_lid = 1; + return NOTIFY_OK; } - if (dev_priv->modeset_restore == MODESET_DONE) - goto exit; + if (!dev_priv->modeset_on_lid) + return NOTIFY_OK; + + dev_priv->modeset_on_lid = 0; drm_modeset_lock_all(dev); intel_modeset_setup_hw_state(dev, true); drm_modeset_unlock_all(dev); - dev_priv->modeset_restore = MODESET_DONE; - -exit: - mutex_unlock(&dev_priv->modeset_restore_lock); return NOTIFY_OK; } @@ -1100,7 +1093,6 @@ bool intel_lvds_init(struct drm_device *dev) DRM_MODE_ENCODER_LVDS); intel_encoder->enable = intel_enable_lvds; - intel_encoder->pre_enable = intel_pre_enable_lvds; intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds; intel_encoder->disable = intel_disable_lvds; intel_encoder->get_hw_state = intel_lvds_get_hw_state; diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index a3730e0289e5..bee8cb6108a7 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -321,9 +321,6 @@ void intel_panel_enable_backlight(struct drm_device *dev, if (dev_priv->backlight_level == 0) dev_priv->backlight_level = intel_panel_get_max_backlight(dev); - dev_priv->backlight_enabled = true; - intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); - if (INTEL_INFO(dev)->gen >= 4) { uint32_t reg, tmp; @@ -359,12 +356,12 @@ void intel_panel_enable_backlight(struct drm_device *dev, } set_level: - /* Check the current backlight level and try to set again if it's zero. - * On some machines, BLC_PWM_CPU_CTL is cleared to zero automatically - * when BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1 are written. + /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. + * BLC_PWM_CPU_CTL may be cleared to zero automatically when these + * registers are set. */ - if (!intel_panel_get_backlight(dev)) - intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); + dev_priv->backlight_enabled = true; + intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); } static void intel_panel_init_backlight(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index 61fee7fcdc2c..7c9a6d11700e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -2289,6 +2289,7 @@ intel_alloc_context_page(struct drm_device *dev) i915_gem_object_unpin(ctx); err_unref: drm_gem_object_unreference(&ctx->base); + mutex_unlock(&dev->struct_mutex); return NULL; } @@ -3583,19 +3584,6 @@ static void cpt_init_clock_gating(struct drm_device *dev) } } -static void gen6_check_mch_setup(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t tmp; - - tmp = I915_READ(MCH_SSKPD); - if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL) { - DRM_INFO("Wrong MCH_SSKPD value: 0x%08x\n", tmp); - DRM_INFO("This can cause pipe underruns and display issues.\n"); - DRM_INFO("Please upgrade your BIOS to fix this.\n"); - } -} - static void gen6_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -3688,8 +3676,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI)); cpt_init_clock_gating(dev); - - gen6_check_mch_setup(dev); } static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) @@ -3875,8 +3861,6 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); cpt_init_clock_gating(dev); - - gen6_check_mch_setup(dev); } static void valleyview_init_clock_gating(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 1d5d613eb6be..00525ff59045 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -318,7 +318,6 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring, * TLB invalidate requires a post-sync write. */ flags |= PIPE_CONTROL_QW_WRITE; - flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; /* Workaround: we must issue a pipe_control with CS-stall bit * set before a pipe_control command that has the state cache @@ -332,7 +331,7 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring, intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); intel_ring_emit(ring, flags); - intel_ring_emit(ring, scratch_addr); + intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, 0); intel_ring_advance(ring); @@ -468,9 +467,6 @@ init_pipe_control(struct intel_ring_buffer *ring) if (pc->cpu_page == NULL) goto err_unpin; - DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n", - ring->name, pc->gtt_offset); - pc->obj = obj; ring->private = pc; return 0; diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c index d086e48a831a..f8293061d6bd 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sprite.c +++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c @@ -50,7 +50,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, u32 sprctl, sprscale = 0; unsigned long sprsurf_offset, linear_offset; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); - bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; sprctl = I915_READ(SPRCTL(pipe)); @@ -90,9 +89,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, sprctl |= SPRITE_TRICKLE_FEED_DISABLE; sprctl |= SPRITE_ENABLE; - if (IS_HASWELL(dev)) - sprctl |= SPRITE_PIPE_CSC_ENABLE; - /* Sizes are 0 based */ src_w--; src_h--; @@ -107,15 +103,19 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, * when scaling is disabled. */ if (crtc_w != src_w || crtc_h != src_h) { - dev_priv->sprite_scaling_enabled |= 1 << pipe; - - if (!scaling_was_enabled) { + if (!dev_priv->sprite_scaling_enabled) { + dev_priv->sprite_scaling_enabled = true; intel_update_watermarks(dev); intel_wait_for_vblank(dev, pipe); } sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; - } else - dev_priv->sprite_scaling_enabled &= ~(1 << pipe); + } else { + if (dev_priv->sprite_scaling_enabled) { + dev_priv->sprite_scaling_enabled = false; + /* potentially re-enable LP watermarks */ + intel_update_watermarks(dev); + } + } I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); @@ -141,10 +141,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, I915_WRITE(SPRCTL(pipe), sprctl); I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset); POSTING_READ(SPRSURF(pipe)); - - /* potentially re-enable LP watermarks */ - if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) - intel_update_watermarks(dev); } static void @@ -154,7 +150,6 @@ ivb_disable_plane(struct drm_plane *plane) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(plane); int pipe = intel_plane->pipe; - bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); /* Can't leave the scaler enabled... */ @@ -164,11 +159,8 @@ ivb_disable_plane(struct drm_plane *plane) I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); POSTING_READ(SPRSURF(pipe)); - dev_priv->sprite_scaling_enabled &= ~(1 << pipe); - - /* potentially re-enable LP watermarks */ - if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) - intel_update_watermarks(dev); + dev_priv->sprite_scaling_enabled = false; + intel_update_watermarks(dev); } static int diff --git a/trunk/drivers/gpu/drm/nouveau/Kconfig b/trunk/drivers/gpu/drm/nouveau/Kconfig index a7ff6d5a34b9..47ccc1ad5405 100644 --- a/trunk/drivers/gpu/drm/nouveau/Kconfig +++ b/trunk/drivers/gpu/drm/nouveau/Kconfig @@ -11,9 +11,8 @@ config DRM_NOUVEAU select FRAMEBUFFER_CONSOLE if !EXPERT select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT - select X86_PLATFORM_DEVICES if ACPI && X86 - select ACPI_WMI if ACPI && X86 - select MXM_WMI if ACPI && X86 + select ACPI_WMI if ACPI + select MXM_WMI if ACPI select POWER_SUPPLY help Choose this option for open-source nVidia support. diff --git a/trunk/drivers/gpu/drm/nouveau/Makefile b/trunk/drivers/gpu/drm/nouveau/Makefile index 90f9140eeefd..ab25752a0b1e 100644 --- a/trunk/drivers/gpu/drm/nouveau/Makefile +++ b/trunk/drivers/gpu/drm/nouveau/Makefile @@ -11,7 +11,6 @@ nouveau-y := core/core/client.o nouveau-y += core/core/engctx.o nouveau-y += core/core/engine.o nouveau-y += core/core/enum.o -nouveau-y += core/core/event.o nouveau-y += core/core/falcon.o nouveau-y += core/core/gpuobj.o nouveau-y += core/core/handle.o @@ -41,11 +40,6 @@ 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/therm.o -nouveau-y += core/subdev/bios/xpio.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/nvc0.o nouveau-y += core/subdev/clock/nv04.o nouveau-y += core/subdev/clock/nv40.o nouveau-y += core/subdev/clock/nv50.o @@ -91,16 +85,9 @@ nouveau-y += core/subdev/gpio/base.o nouveau-y += core/subdev/gpio/nv10.o nouveau-y += core/subdev/gpio/nv50.o nouveau-y += core/subdev/gpio/nvd0.o -nouveau-y += core/subdev/gpio/nve0.o nouveau-y += core/subdev/i2c/base.o -nouveau-y += core/subdev/i2c/anx9805.o nouveau-y += core/subdev/i2c/aux.o nouveau-y += core/subdev/i2c/bit.o -nouveau-y += core/subdev/i2c/nv04.o -nouveau-y += core/subdev/i2c/nv4e.o -nouveau-y += core/subdev/i2c/nv50.o -nouveau-y += core/subdev/i2c/nv94.o -nouveau-y += core/subdev/i2c/nvd0.o nouveau-y += core/subdev/ibus/nvc0.o nouveau-y += core/subdev/ibus/nve0.o nouveau-y += core/subdev/instmem/base.o @@ -119,15 +106,10 @@ nouveau-y += core/subdev/mxm/mxms.o nouveau-y += core/subdev/mxm/nv50.o nouveau-y += core/subdev/therm/base.o nouveau-y += core/subdev/therm/fan.o -nouveau-y += core/subdev/therm/fannil.o -nouveau-y += core/subdev/therm/fanpwm.o -nouveau-y += core/subdev/therm/fantog.o nouveau-y += core/subdev/therm/ic.o -nouveau-y += core/subdev/therm/temp.o nouveau-y += core/subdev/therm/nv40.o nouveau-y += core/subdev/therm/nv50.o -nouveau-y += core/subdev/therm/nva3.o -nouveau-y += core/subdev/therm/nvd0.o +nouveau-y += core/subdev/therm/temp.o nouveau-y += core/subdev/timer/base.o nouveau-y += core/subdev/timer/nv04.o nouveau-y += core/subdev/vm/base.o @@ -150,7 +132,6 @@ nouveau-y += core/engine/copy/nvc0.o 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/disp/base.o nouveau-y += core/engine/disp/nv04.o nouveau-y += core/engine/disp/nv50.o nouveau-y += core/engine/disp/nv84.o @@ -160,13 +141,11 @@ nouveau-y += core/engine/disp/nva3.o nouveau-y += core/engine/disp/nvd0.o nouveau-y += core/engine/disp/nve0.o nouveau-y += core/engine/disp/dacnv50.o -nouveau-y += core/engine/disp/dport.o nouveau-y += core/engine/disp/hdanva3.o nouveau-y += core/engine/disp/hdanvd0.o nouveau-y += core/engine/disp/hdminv84.o nouveau-y += core/engine/disp/hdminva3.o nouveau-y += core/engine/disp/hdminvd0.o -nouveau-y += core/engine/disp/piornv50.o nouveau-y += core/engine/disp/sornv50.o nouveau-y += core/engine/disp/sornv94.o nouveau-y += core/engine/disp/sornvd0.o @@ -215,8 +194,7 @@ nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o nouveau-y += nouveau_prime.o nouveau_abi16.o -nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o -nouveau-y += nv50_fence.o nv84_fence.o nvc0_fence.o +nouveau-y += nv04_fence.o nv10_fence.o nv50_fence.o nv84_fence.o nvc0_fence.o # drm/kms nouveau-y += nouveau_bios.o nouveau_fbcon.o nouveau_display.o @@ -238,10 +216,7 @@ nouveau-y += nouveau_mem.o # other random bits nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o -ifdef CONFIG_X86 nouveau-$(CONFIG_ACPI) += nouveau_acpi.o -endif nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o -nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/client.c b/trunk/drivers/gpu/drm/nouveau/core/core/client.c index 295c22165eac..8bbb58f94a19 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/client.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/client.c @@ -99,13 +99,3 @@ nouveau_client_fini(struct nouveau_client *client, bool suspend) nv_debug(client, "%s completed with %d\n", name[suspend], ret); return ret; } - -const char * -nouveau_client_name(void *obj) -{ - const char *client_name = "unknown"; - struct nouveau_client *client = nouveau_client(obj); - if (client) - client_name = client->name; - return client_name; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/enum.c b/trunk/drivers/gpu/drm/nouveau/core/core/enum.c index dd434790ccc4..7cc7133d82de 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/enum.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/enum.c @@ -40,15 +40,14 @@ nouveau_enum_find(const struct nouveau_enum *en, u32 value) return NULL; } -const struct nouveau_enum * +void nouveau_enum_print(const struct nouveau_enum *en, u32 value) { en = nouveau_enum_find(en, value); if (en) - pr_cont("%s", en->name); + printk("%s", en->name); else - pr_cont("(unknown enum 0x%08x)", value); - return en; + printk("(unknown enum 0x%08x)", value); } void @@ -56,7 +55,7 @@ nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value) { while (bf->name) { if (value & bf->mask) { - pr_cont(" %s", bf->name); + printk(" %s", bf->name); value &= ~bf->mask; } @@ -64,5 +63,5 @@ nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value) } if (value) - pr_cont(" (unknown bits 0x%08x)", value); + printk(" (unknown bits 0x%08x)", value); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/event.c b/trunk/drivers/gpu/drm/nouveau/core/core/event.c deleted file mode 100644 index 6d01e0f0fc8a..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/core/event.c +++ /dev/null @@ -1,106 +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. - */ - -#include -#include - -static void -nouveau_event_put_locked(struct nouveau_event *event, int index, - struct nouveau_eventh *handler) -{ - if (!--event->index[index].refs) - event->disable(event, index); - list_del(&handler->head); -} - -void -nouveau_event_put(struct nouveau_event *event, int index, - struct nouveau_eventh *handler) -{ - unsigned long 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); -} - -void -nouveau_event_get(struct nouveau_event *event, int index, - struct nouveau_eventh *handler) -{ - unsigned long flags; - - spin_lock_irqsave(&event->lock, flags); - if (index < event->index_nr) { - list_add(&handler->head, &event->index[index].list); - if (!event->index[index].refs++) - event->enable(event, index); - } - spin_unlock_irqrestore(&event->lock, flags); -} - -void -nouveau_event_trigger(struct nouveau_event *event, int index) -{ - struct nouveau_eventh *handler, *temp; - unsigned long flags; - - if (index >= event->index_nr) - return; - - 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->lock, flags); -} - -void -nouveau_event_destroy(struct nouveau_event **pevent) -{ - struct nouveau_event *event = *pevent; - if (event) { - kfree(event); - *pevent = NULL; - } -} - -int -nouveau_event_create(int index_nr, struct nouveau_event **pevent) -{ - struct nouveau_event *event; - int i; - - event = *pevent = kzalloc(sizeof(*event) + index_nr * - sizeof(event->index[0]), GFP_KERNEL); - if (!event) - return -ENOMEM; - - spin_lock_init(&event->lock); - for (i = 0; i < index_nr; i++) - INIT_LIST_HEAD(&event->index[i].list); - event->index_nr = index_nr; - return 0; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c b/trunk/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c index d6dc2a65ccd1..283248c7b050 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c @@ -22,7 +22,6 @@ * Authors: Ben Skeggs */ -#include #include #include #include @@ -101,9 +100,8 @@ nva3_copy_intr(struct nouveau_subdev *subdev) if (stat & 0x00000040) { nv_error(falcon, "DISPATCH_ERROR ["); nouveau_enum_print(nva3_copy_isr_error_name, ssta); - pr_cont("] ch %d [0x%010llx %s] subc %d mthd 0x%04x data 0x%08x\n", - chid, inst << 12, nouveau_client_name(engctx), subc, - mthd, data); + printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n", + chid, inst << 12, subc, mthd, data); nv_wo32(falcon, 0x004, 0x00000040); stat &= ~0x00000040; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c b/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c index 5bc021f471f9..b97490512723 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c @@ -22,7 +22,6 @@ * Authors: Ben Skeggs */ -#include #include #include #include @@ -127,11 +126,10 @@ nv84_crypt_intr(struct nouveau_subdev *subdev) chid = pfifo->chid(pfifo, engctx); if (stat) { - nv_error(priv, "%s", ""); + nv_error(priv, ""); nouveau_bitfield_print(nv84_crypt_intr_mask, stat); - pr_cont(" ch %d [0x%010llx %s] mthd 0x%04x data 0x%08x\n", - chid, (u64)inst << 12, nouveau_client_name(engctx), - mthd, data); + printk(" ch %d [0x%010llx] mthd 0x%04x data 0x%08x\n", + chid, (u64)inst << 12, mthd, data); } nv_wr32(priv, 0x102130, stat); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c b/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c index 8bf8955051d4..21986f3bf0c8 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c @@ -22,7 +22,6 @@ * Authors: Ben Skeggs */ -#include #include #include #include @@ -103,9 +102,8 @@ nv98_crypt_intr(struct nouveau_subdev *subdev) if (stat & 0x00000040) { nv_error(priv, "DISPATCH_ERROR ["); nouveau_enum_print(nv98_crypt_isr_error_name, ssta); - pr_cont("] ch %d [0x%010llx %s] subc %d mthd 0x%04x data 0x%08x\n", - chid, (u64)inst << 12, nouveau_client_name(engctx), - subc, mthd, data); + printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n", + chid, (u64)inst << 12, subc, mthd, data); nv_wr32(priv, 0x087004, 0x00000040); stat &= ~0x00000040; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/base.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/base.c deleted file mode 100644 index 7a5cae42834f..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/base.c +++ /dev/null @@ -1,52 +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 - -void -_nouveau_disp_dtor(struct nouveau_object *object) -{ - struct nouveau_disp *disp = (void *)object; - nouveau_event_destroy(&disp->vblank); - nouveau_engine_destroy(&disp->base); -} - -int -nouveau_disp_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, int heads, - const char *intname, const char *extname, - int length, void **pobject) -{ - struct nouveau_disp *disp; - int ret; - - ret = nouveau_engine_create_(parent, engine, oclass, true, - intname, extname, length, pobject); - disp = *pobject; - if (ret) - return ret; - - return nouveau_event_create(heads, &disp->vblank); -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.c deleted file mode 100644 index fa27b02ff829..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.c +++ /dev/null @@ -1,346 +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 -#include -#include -#include -#include - -#include - -#include "dport.h" - -#define DBG(fmt, args...) nv_debug(dp->disp, "DP:%04x:%04x: " fmt, \ - dp->outp->hasht, dp->outp->hashm, ##args) -#define ERR(fmt, args...) nv_error(dp->disp, "DP:%04x:%04x: " fmt, \ - dp->outp->hasht, dp->outp->hashm, ##args) - -/****************************************************************************** - * link training - *****************************************************************************/ -struct dp_state { - const struct nouveau_dp_func *func; - struct nouveau_disp *disp; - struct dcb_output *outp; - struct nvbios_dpout info; - u8 version; - struct nouveau_i2c_port *aux; - int head; - u8 dpcd[4]; - int link_nr; - u32 link_bw; - u8 stat[6]; - u8 conf[4]; -}; - -static int -dp_set_link_config(struct dp_state *dp) -{ - struct nouveau_disp *disp = dp->disp; - struct nouveau_bios *bios = nouveau_bios(disp); - struct nvbios_init init = { - .subdev = nv_subdev(dp->disp), - .bios = bios, - .offset = 0x0000, - .outp = dp->outp, - .crtc = dp->head, - .execute = 1, - }; - u32 lnkcmp; - u8 sink[2]; - - 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) { - while ((dp->link_bw / 10) < nv_ro16(bios, lnkcmp)) - lnkcmp += 4; - init.offset = nv_ro16(bios, lnkcmp + 2); - } else { - while ((dp->link_bw / 27000) < nv_ro08(bios, lnkcmp)) - lnkcmp += 3; - init.offset = nv_ro16(bios, lnkcmp + 1); - } - - nvbios_exec(&init); - } - - 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 -dp_set_training_pattern(struct dp_state *dp, u8 pattern) -{ - u8 sink_tp; - - DBG("training pattern %d\n", pattern); - dp->func->pattern(dp->disp, dp->outp, dp->head, pattern); - - nv_rdaux(dp->aux, DPCD_LC02, &sink_tp, 1); - sink_tp &= ~DPCD_LC02_TRAINING_PATTERN_SET; - sink_tp |= pattern; - nv_wraux(dp->aux, DPCD_LC02, &sink_tp, 1); -} - -static int -dp_link_train_commit(struct dp_state *dp) -{ - int i; - - for (i = 0; i < dp->link_nr; i++) { - u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf; - u8 lpre = (lane & 0x0c) >> 2; - u8 lvsw = (lane & 0x03) >> 0; - - dp->conf[i] = (lpre << 3) | lvsw; - if (lvsw == 3) - dp->conf[i] |= DPCD_LC03_MAX_SWING_REACHED; - if (lpre == 3) - dp->conf[i] |= DPCD_LC03_MAX_PRE_EMPHASIS_REACHED; - - DBG("config lane %d %02x\n", i, dp->conf[i]); - dp->func->drv_ctl(dp->disp, dp->outp, dp->head, i, lvsw, lpre); - } - - return nv_wraux(dp->aux, DPCD_LC03(0), dp->conf, 4); -} - -static int -dp_link_train_update(struct dp_state *dp, u32 delay) -{ - int ret; - - udelay(delay); - - ret = nv_rdaux(dp->aux, DPCD_LS02, dp->stat, 6); - if (ret) - return ret; - - DBG("status %*ph\n", 6, dp->stat); - return 0; -} - -static int -dp_link_train_cr(struct dp_state *dp) -{ - bool cr_done = false, abort = false; - int voltage = dp->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET; - int tries = 0, i; - - dp_set_training_pattern(dp, 1); - - do { - if (dp_link_train_commit(dp) || - dp_link_train_update(dp, 100)) - break; - - cr_done = true; - for (i = 0; i < dp->link_nr; i++) { - u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; - if (!(lane & DPCD_LS02_LANE0_CR_DONE)) { - cr_done = false; - if (dp->conf[i] & DPCD_LC03_MAX_SWING_REACHED) - abort = true; - break; - } - } - - if ((dp->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET) != voltage) { - voltage = dp->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET; - tries = 0; - } - } while (!cr_done && !abort && ++tries < 5); - - return cr_done ? 0 : -1; -} - -static int -dp_link_train_eq(struct dp_state *dp) -{ - bool eq_done, cr_done = true; - int tries = 0, i; - - dp_set_training_pattern(dp, 2); - - do { - if (dp_link_train_update(dp, 400)) - break; - - eq_done = !!(dp->stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE); - for (i = 0; i < dp->link_nr && eq_done; i++) { - u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; - if (!(lane & DPCD_LS02_LANE0_CR_DONE)) - cr_done = false; - if (!(lane & DPCD_LS02_LANE0_CHANNEL_EQ_DONE) || - !(lane & DPCD_LS02_LANE0_SYMBOL_LOCKED)) - eq_done = false; - } - - if (dp_link_train_commit(dp)) - break; - } while (!eq_done && cr_done && ++tries <= 5); - - return eq_done ? 0 : -1; -} - -static void -dp_link_train_init(struct dp_state *dp, bool spread) -{ - struct nvbios_init init = { - .subdev = nv_subdev(dp->disp), - .bios = nouveau_bios(dp->disp), - .outp = dp->outp, - .crtc = dp->head, - .execute = 1, - }; - - /* set desired spread */ - if (spread) - init.offset = dp->info.script[2]; - else - init.offset = dp->info.script[3]; - nvbios_exec(&init); - - /* pre-train script */ - init.offset = dp->info.script[0]; - nvbios_exec(&init); -} - -static void -dp_link_train_fini(struct dp_state *dp) -{ - struct nvbios_init init = { - .subdev = nv_subdev(dp->disp), - .bios = nouveau_bios(dp->disp), - .outp = dp->outp, - .crtc = dp->head, - .execute = 1, - }; - - /* post-train script */ - init.offset = dp->info.script[1], - nvbios_exec(&init); -} - -int -nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, - struct dcb_output *outp, int head, u32 datarate) -{ - struct nouveau_bios *bios = nouveau_bios(disp); - struct nouveau_i2c *i2c = nouveau_i2c(disp); - struct dp_state _dp = { - .disp = disp, - .func = func, - .outp = outp, - .head = head, - }, *dp = &_dp; - const u32 bw_list[] = { 270000, 162000, 0 }; - const u32 *link_bw = bw_list; - u8 hdr, cnt, len; - u32 data; - int ret; - - /* find the bios displayport data relevant to this output */ - data = nvbios_dpout_match(bios, outp->hasht, outp->hashm, &dp->version, - &hdr, &cnt, &len, &dp->info); - if (!data) { - ERR("bios data not found\n"); - return -EINVAL; - } - - /* acquire the aux channel and fetch some info about the display */ - if (outp->location) - dp->aux = i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(outp->extdev)); - else - dp->aux = i2c->find(i2c, NV_I2C_TYPE_DCBI2C(outp->i2c_index)); - if (!dp->aux) { - ERR("no aux channel?!\n"); - return -ENODEV; - } - - ret = nv_rdaux(dp->aux, 0x00000, dp->dpcd, sizeof(dp->dpcd)); - if (ret) { - ERR("failed to read DPCD\n"); - return ret; - } - - /* adjust required bandwidth for 8B/10B coding overhead */ - datarate = (datarate / 8) * 10; - - /* enable down-spreading and execute pre-train script from vbios */ - dp_link_train_init(dp, dp->dpcd[3] & 0x01); - - /* start off at highest link rate supported by encoder and display */ - while (*link_bw > (dp->dpcd[1] * 27000)) - link_bw++; - - 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) - dp->link_nr >>= 1; - - /* drop link rate to minimum with this lane count */ - while ((link_bw[1] * dp->link_nr) > datarate) - link_bw++; - dp->link_bw = link_bw[0]; - - /* program selected link configuration */ - ret = dp_set_link_config(dp); - if (ret == 0) { - /* attempt to train the link at this configuration */ - memset(dp->stat, 0x00, sizeof(dp->stat)); - if (!dp_link_train_cr(dp) && - !dp_link_train_eq(dp)) - break; - } else - if (ret >= 1) { - /* dp_set_link_config() handled training */ - break; - } - - /* retry at lower rate */ - link_bw++; - } - - /* finish link training */ - dp_set_training_pattern(dp, 0); - - /* execute post-train script from vbios */ - dp_link_train_fini(dp); - return true; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.h b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.h deleted file mode 100644 index 0e1bbd18ff6c..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/dport.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef __NVKM_DISP_DPORT_H__ -#define __NVKM_DISP_DPORT_H__ - -/* DPCD Receiver Capabilities */ -#define DPCD_RC00 0x00000 -#define DPCD_RC00_DPCD_REV 0xff -#define DPCD_RC01 0x00001 -#define DPCD_RC01_MAX_LINK_RATE 0xff -#define DPCD_RC02 0x00002 -#define DPCD_RC02_ENHANCED_FRAME_CAP 0x80 -#define DPCD_RC02_MAX_LANE_COUNT 0x1f -#define DPCD_RC03 0x00003 -#define DPCD_RC03_MAX_DOWNSPREAD 0x01 - -/* DPCD Link Configuration */ -#define DPCD_LC00 0x00100 -#define DPCD_LC00_LINK_BW_SET 0xff -#define DPCD_LC01 0x00101 -#define DPCD_LC01_ENHANCED_FRAME_EN 0x80 -#define DPCD_LC01_LANE_COUNT_SET 0x1f -#define DPCD_LC02 0x00102 -#define DPCD_LC02_TRAINING_PATTERN_SET 0x03 -#define DPCD_LC03(l) ((l) + 0x00103) -#define DPCD_LC03_MAX_PRE_EMPHASIS_REACHED 0x20 -#define DPCD_LC03_PRE_EMPHASIS_SET 0x18 -#define DPCD_LC03_MAX_SWING_REACHED 0x04 -#define DPCD_LC03_VOLTAGE_SWING_SET 0x03 - -/* DPCD Link/Sink Status */ -#define DPCD_LS02 0x00202 -#define DPCD_LS02_LANE1_SYMBOL_LOCKED 0x40 -#define DPCD_LS02_LANE1_CHANNEL_EQ_DONE 0x20 -#define DPCD_LS02_LANE1_CR_DONE 0x10 -#define DPCD_LS02_LANE0_SYMBOL_LOCKED 0x04 -#define DPCD_LS02_LANE0_CHANNEL_EQ_DONE 0x02 -#define DPCD_LS02_LANE0_CR_DONE 0x01 -#define DPCD_LS03 0x00203 -#define DPCD_LS03_LANE3_SYMBOL_LOCKED 0x40 -#define DPCD_LS03_LANE3_CHANNEL_EQ_DONE 0x20 -#define DPCD_LS03_LANE3_CR_DONE 0x10 -#define DPCD_LS03_LANE2_SYMBOL_LOCKED 0x04 -#define DPCD_LS03_LANE2_CHANNEL_EQ_DONE 0x02 -#define DPCD_LS03_LANE2_CR_DONE 0x01 -#define DPCD_LS04 0x00204 -#define DPCD_LS04_LINK_STATUS_UPDATED 0x80 -#define DPCD_LS04_DOWNSTREAM_PORT_STATUS_CHANGED 0x40 -#define DPCD_LS04_INTERLANE_ALIGN_DONE 0x01 -#define DPCD_LS06 0x00206 -#define DPCD_LS06_LANE1_PRE_EMPHASIS 0xc0 -#define DPCD_LS06_LANE1_VOLTAGE_SWING 0x30 -#define DPCD_LS06_LANE0_PRE_EMPHASIS 0x0c -#define DPCD_LS06_LANE0_VOLTAGE_SWING 0x03 -#define DPCD_LS07 0x00207 -#define DPCD_LS07_LANE3_PRE_EMPHASIS 0xc0 -#define DPCD_LS07_LANE3_VOLTAGE_SWING 0x30 -#define DPCD_LS07_LANE2_PRE_EMPHASIS 0x0c -#define DPCD_LS07_LANE2_VOLTAGE_SWING 0x03 - -struct nouveau_disp; -struct dcb_output; - -struct nouveau_dp_func { - int (*pattern)(struct nouveau_disp *, struct dcb_output *, - int head, int pattern); - int (*lnk_ctl)(struct nouveau_disp *, struct dcb_output *, int head, - int link_nr, int link_bw, bool enh_frame); - int (*drv_ctl)(struct nouveau_disp *, struct dcb_output *, int head, - int lane, int swing, int preem); -}; - -extern const struct nouveau_dp_func nv94_sor_dp_func; -extern const struct nouveau_dp_func nvd0_sor_dp_func; -extern const struct nouveau_dp_func nv50_pior_dp_func; - -int nouveau_dp_train(struct nouveau_disp *, const struct nouveau_dp_func *, - struct dcb_output *, int, u32); - -#endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c index 05e903f08a36..1c919f2af89f 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c @@ -24,33 +24,21 @@ #include -#include -#include - struct nv04_disp_priv { struct nouveau_disp base; }; static struct nouveau_oclass nv04_disp_sclass[] = { - { NV04_DISP_CLASS, &nouveau_object_ofuncs }, {}, }; -/******************************************************************************* - * Display engine implementation - ******************************************************************************/ - -static void -nv04_disp_vblank_enable(struct nouveau_event *event, int head) -{ - nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000001); -} - static void -nv04_disp_vblank_disable(struct nouveau_event *event, int head) +nv04_disp_intr_vblank(struct nv04_disp_priv *priv, int crtc) { - nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000000); + struct nouveau_disp *disp = &priv->base; + if (disp->vblank.notify) + disp->vblank.notify(disp->vblank.data, crtc); } static void @@ -61,25 +49,25 @@ nv04_disp_intr(struct nouveau_subdev *subdev) u32 crtc1 = nv_rd32(priv, 0x602100); if (crtc0 & 0x00000001) { - nouveau_event_trigger(priv->base.vblank, 0); + nv04_disp_intr_vblank(priv, 0); nv_wr32(priv, 0x600100, 0x00000001); } if (crtc1 & 0x00000001) { - nouveau_event_trigger(priv->base.vblank, 1); + nv04_disp_intr_vblank(priv, 1); nv_wr32(priv, 0x602100, 0x00000001); } } static int nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { struct nv04_disp_priv *priv; int ret; - ret = nouveau_disp_create(parent, engine, oclass, 2, "DISPLAY", + ret = nouveau_disp_create(parent, engine, oclass, "DISPLAY", "display", &priv); *pobject = nv_object(priv); if (ret) @@ -87,9 +75,6 @@ nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nv04_disp_sclass; nv_subdev(priv)->intr = nv04_disp_intr; - priv->base.vblank->priv = priv; - priv->base.vblank->enable = nv04_disp_vblank_enable; - priv->base.vblank->disable = nv04_disp_vblank_disable; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 5fa13267bd9f..ca1a7d76a95b 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include "nv50.h" @@ -333,7 +335,7 @@ nv50_disp_sync_ctor(struct nouveau_object *parent, struct nv50_disp_dmac *dmac; int ret; - if (size < sizeof(*args) || args->head > 1) + if (size < sizeof(*data) || args->head > 1) return -EINVAL; ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, @@ -372,7 +374,7 @@ nv50_disp_ovly_ctor(struct nouveau_object *parent, struct nv50_disp_dmac *dmac; int ret; - if (size < sizeof(*args) || args->head > 1) + if (size < sizeof(*data) || args->head > 1) return -EINVAL; ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, @@ -541,18 +543,6 @@ nv50_disp_curs_ofuncs = { * Base display object ******************************************************************************/ -static void -nv50_disp_base_vblank_enable(struct nouveau_event *event, int head) -{ - nv_mask(event->priv, 0x61002c, (1 << head), (1 << head)); -} - -static void -nv50_disp_base_vblank_disable(struct nouveau_event *event, int head) -{ - nv_mask(event->priv, 0x61002c, (1 << head), (0 << head)); -} - static int nv50_disp_base_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -569,9 +559,6 @@ nv50_disp_base_ctor(struct nouveau_object *parent, if (ret) return ret; - priv->base.vblank->priv = priv; - priv->base.vblank->enable = nv50_disp_base_vblank_enable; - priv->base.vblank->disable = nv50_disp_base_vblank_disable; return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht); } @@ -626,7 +613,7 @@ nv50_disp_base_init(struct nouveau_object *object) nv_wr32(priv, 0x6101e0 + (i * 0x04), tmp); } - /* ... PIOR caps */ + /* ... EXT caps */ for (i = 0; i < 3; i++) { tmp = nv_rd32(priv, 0x61e000 + (i * 0x800)); nv_wr32(priv, 0x6101f0 + (i * 0x04), tmp); @@ -678,9 +665,6 @@ nv50_disp_base_omthds[] = { { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; @@ -772,6 +756,50 @@ nv50_disp_intr_error(struct nv50_disp_priv *priv) } } +static void +nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) +{ + struct nouveau_bar *bar = nouveau_bar(priv); + struct nouveau_disp *disp = &priv->base; + struct nouveau_software_chan *chan, *temp; + unsigned long flags; + + spin_lock_irqsave(&disp->vblank.lock, flags); + list_for_each_entry_safe(chan, temp, &disp->vblank.list, vblank.head) { + if (chan->vblank.crtc != crtc) + continue; + + if (nv_device(priv)->chipset >= 0xc0) { + nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); + bar->flush(bar); + nv_wr32(priv, 0x06000c, + upper_32_bits(chan->vblank.offset)); + nv_wr32(priv, 0x060010, + lower_32_bits(chan->vblank.offset)); + nv_wr32(priv, 0x060014, chan->vblank.value); + } else { + nv_wr32(priv, 0x001704, chan->vblank.channel); + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); + bar->flush(bar); + if (nv_device(priv)->chipset == 0x50) { + nv_wr32(priv, 0x001570, chan->vblank.offset); + nv_wr32(priv, 0x001574, chan->vblank.value); + } else { + nv_wr32(priv, 0x060010, chan->vblank.offset); + nv_wr32(priv, 0x060014, chan->vblank.value); + } + } + + list_del(&chan->vblank.head); + if (disp->vblank.put) + disp->vblank.put(disp->vblank.data, crtc); + } + spin_unlock_irqrestore(&disp->vblank.lock, flags); + + if (disp->vblank.notify) + disp->vblank.notify(disp->vblank.data, crtc); +} + static u16 exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, @@ -783,8 +811,8 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, if (outp < 4) { type = DCB_OUTPUT_ANALOG; mask = 0; - } else - if (outp < 8) { + } else { + outp -= 4; switch (ctrl & 0x00000f00) { case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break; case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break; @@ -796,17 +824,6 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl); return 0x0000; } - outp -= 4; - } else { - outp = outp - 8; - type = 0x0010; - mask = 0; - switch (ctrl & 0x00000f00) { - case 0x00000000: type |= priv->pior.type[outp]; break; - default: - nv_error(priv, "unknown PIOR mc 0x%08x\n", ctrl); - return 0x0000; - } } mask = 0x00c0 & (mask << 6); @@ -817,10 +834,6 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, if (!data) return 0x0000; - /* off-chip encoders require matching the exact encoder type */ - if (dcb->location != 0) - type |= dcb->extdev << 8; - return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info); } @@ -835,11 +848,9 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) u32 ctrl = 0x00000000; int i; - /* DAC */ for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); - /* SOR */ if (!(ctrl & (1 << head))) { if (nv_device(priv)->chipset < 0x90 || nv_device(priv)->chipset == 0x92 || @@ -854,13 +865,6 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) } } - /* PIOR */ - if (!(ctrl & (1 << head))) { - for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) - ctrl = nv_rd32(priv, 0x610b84 + (i * 8)); - i += 8; - } - if (!(ctrl & (1 << head))) return false; i--; @@ -890,15 +894,13 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, struct nvbios_outp info1; struct nvbios_ocfg info2; u8 ver, hdr, cnt, len; + u16 data, conf; u32 ctrl = 0x00000000; - u32 data, conf = ~0; int i; - /* DAC */ for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); - /* SOR */ if (!(ctrl & (1 << head))) { if (nv_device(priv)->chipset < 0x90 || nv_device(priv)->chipset == 0x92 || @@ -913,46 +915,34 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, } } - /* PIOR */ - if (!(ctrl & (1 << head))) { - for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) - ctrl = nv_rd32(priv, 0x610b80 + (i * 8)); - i += 8; - } - if (!(ctrl & (1 << head))) - return conf; + return 0x0000; i--; data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1); if (!data) - return conf; - - if (outp->location == 0) { - switch (outp->type) { - case DCB_OUTPUT_TMDS: - conf = (ctrl & 0x00000f00) >> 8; - if (pclk >= 165000) - conf |= 0x0100; - break; - case DCB_OUTPUT_LVDS: - conf = priv->sor.lvdsconf; - break; - case DCB_OUTPUT_DP: - conf = (ctrl & 0x00000f00) >> 8; - break; - case DCB_OUTPUT_ANALOG: - default: - conf = 0x00ff; - break; - } - } else { + return 0x0000; + + switch (outp->type) { + case DCB_OUTPUT_TMDS: + conf = (ctrl & 0x00000f00) >> 8; + if (pclk >= 165000) + conf |= 0x0100; + break; + case DCB_OUTPUT_LVDS: + conf = priv->sor.lvdsconf; + break; + case DCB_OUTPUT_DP: conf = (ctrl & 0x00000f00) >> 8; - pclk = pclk / 2; + break; + case DCB_OUTPUT_ANALOG: + default: + conf = 0x00ff; + break; } data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2); - if (data && id < 0xff) { + if (data) { data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); if (data) { struct nvbios_init init = { @@ -964,37 +954,32 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, .execute = 1, }; - nvbios_exec(&init); + if (nvbios_exec(&init)) + return 0x0000; + return conf; } } - return conf; -} - -static void -nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head) -{ - exec_script(priv, head, 1); + return 0x0000; } static void -nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head) +nv50_disp_intr_unk10(struct nv50_disp_priv *priv, u32 super) { - exec_script(priv, head, 2); -} + int head = ffs((super & 0x00000060) >> 5) - 1; + if (head >= 0) { + head = ffs((super & 0x00000180) >> 7) - 1; + if (head >= 0) + exec_script(priv, head, 1); + } -static void -nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head) -{ - struct nouveau_clock *clk = nouveau_clock(priv); - u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; - if (pclk) - clk->pll_set(clk, PLL_VPLL0 + head, pclk); + nv_wr32(priv, 0x610024, 0x00000010); + nv_wr32(priv, 0x610030, 0x80000000); } static void -nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, - struct dcb_output *outp, u32 pclk) +nv50_disp_intr_unk20_dp(struct nv50_disp_priv *priv, + struct dcb_output *outp, u32 pclk) { const int link = !(outp->sorconf.link & 1); const int or = ffs(outp->or) - 1; @@ -1100,54 +1085,53 @@ nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, } static void -nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) +nv50_disp_intr_unk20(struct nv50_disp_priv *priv, u32 super) { struct dcb_output outp; - u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; - u32 hval, hreg = 0x614200 + (head * 0x800); - u32 oval, oreg; - u32 conf = exec_clkcmp(priv, head, 0xff, pclk, &outp); - if (conf != ~0) { - if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) { - u32 soff = (ffs(outp.or) - 1) * 0x08; - u32 ctrl = nv_rd32(priv, 0x610798 + soff); - u32 datarate; - - switch ((ctrl & 0x000f0000) >> 16) { - case 6: datarate = pclk * 30 / 8; break; - case 5: datarate = pclk * 24 / 8; break; - case 2: - default: - datarate = pclk * 18 / 8; - break; - } + u32 addr, mask, data; + int head; - nouveau_dp_train(&priv->base, priv->sor.dp, - &outp, head, datarate); + /* finish detaching encoder? */ + head = ffs((super & 0x00000180) >> 7) - 1; + if (head >= 0) + exec_script(priv, head, 2); + + /* check whether a vpll change is required */ + head = ffs((super & 0x00000600) >> 9) - 1; + if (head >= 0) { + u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; + if (pclk) { + struct nouveau_clock *clk = nouveau_clock(priv); + clk->pll_set(clk, PLL_VPLL0 + head, pclk); } - exec_clkcmp(priv, head, 0, pclk, &outp); - - if (!outp.location && outp.type == DCB_OUTPUT_ANALOG) { - oreg = 0x614280 + (ffs(outp.or) - 1) * 0x800; - oval = 0x00000000; - hval = 0x00000000; - } else - if (!outp.location) { - if (outp.type == DCB_OUTPUT_DP) - nv50_disp_intr_unk20_2_dp(priv, &outp, pclk); - oreg = 0x614300 + (ffs(outp.or) - 1) * 0x800; - oval = (conf & 0x0100) ? 0x00000101 : 0x00000000; - hval = 0x00000000; - } else { - oreg = 0x614380 + (ffs(outp.or) - 1) * 0x800; - oval = 0x00000001; - hval = 0x00000001; - } + nv_mask(priv, 0x614200 + head * 0x800, 0x0000000f, 0x00000000); + } - nv_mask(priv, hreg, 0x0000000f, hval); - nv_mask(priv, oreg, 0x00000707, oval); + /* (re)attach the relevant OR to the head */ + head = ffs((super & 0x00000180) >> 7) - 1; + if (head >= 0) { + u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; + u32 conf = exec_clkcmp(priv, head, 0, pclk, &outp); + if (conf) { + if (outp.type == DCB_OUTPUT_ANALOG) { + addr = 0x614280 + (ffs(outp.or) - 1) * 0x800; + mask = 0xffffffff; + data = 0x00000000; + } else { + if (outp.type == DCB_OUTPUT_DP) + nv50_disp_intr_unk20_dp(priv, &outp, pclk); + addr = 0x614300 + (ffs(outp.or) - 1) * 0x800; + mask = 0x00000707; + data = (conf & 0x0100) ? 0x0101 : 0x0000; + } + + nv_mask(priv, addr, mask, data); + } } + + nv_wr32(priv, 0x610024, 0x00000020); + nv_wr32(priv, 0x610030, 0x80000000); } /* If programming a TMDS output on a SOR that can also be configured for @@ -1159,7 +1143,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) * programmed for DisplayPort. */ static void -nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp) +nv50_disp_intr_unk40_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp) { struct nouveau_bios *bios = nouveau_bios(priv); const int link = !(outp->sorconf.link & 1); @@ -1173,79 +1157,35 @@ nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp } static void -nv50_disp_intr_unk40_0(struct nv50_disp_priv *priv, int head) +nv50_disp_intr_unk40(struct nv50_disp_priv *priv, u32 super) { - struct dcb_output outp; - u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; - if (exec_clkcmp(priv, head, 1, pclk, &outp) != ~0) { - if (outp.location == 0 && outp.type == DCB_OUTPUT_TMDS) - nv50_disp_intr_unk40_0_tmds(priv, &outp); - else - if (outp.location == 1 && outp.type == DCB_OUTPUT_DP) { - u32 soff = (ffs(outp.or) - 1) * 0x08; - u32 ctrl = nv_rd32(priv, 0x610b84 + soff); - u32 datarate; - - switch ((ctrl & 0x000f0000) >> 16) { - case 6: datarate = pclk * 30 / 8; break; - case 5: datarate = pclk * 24 / 8; break; - case 2: - default: - datarate = pclk * 18 / 8; - break; - } - - nouveau_dp_train(&priv->base, priv->pior.dp, - &outp, head, datarate); + int head = ffs((super & 0x00000180) >> 7) - 1; + if (head >= 0) { + struct dcb_output outp; + u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; + if (pclk && exec_clkcmp(priv, head, 1, pclk, &outp)) { + if (outp.type == DCB_OUTPUT_TMDS) + nv50_disp_intr_unk40_tmds(priv, &outp); } } + + nv_wr32(priv, 0x610024, 0x00000040); + nv_wr32(priv, 0x610030, 0x80000000); } -void -nv50_disp_intr_supervisor(struct work_struct *work) +static void +nv50_disp_intr_super(struct nv50_disp_priv *priv, u32 intr1) { - struct nv50_disp_priv *priv = - container_of(work, struct nv50_disp_priv, supervisor); u32 super = nv_rd32(priv, 0x610030); - int head; - nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super); + nv_debug(priv, "supervisor 0x%08x 0x%08x\n", intr1, super); - if (priv->super & 0x00000010) { - for (head = 0; head < priv->head.nr; head++) { - if (!(super & (0x00000020 << head))) - continue; - if (!(super & (0x00000080 << head))) - continue; - nv50_disp_intr_unk10_0(priv, head); - } - } else - if (priv->super & 0x00000020) { - for (head = 0; head < priv->head.nr; head++) { - if (!(super & (0x00000080 << head))) - continue; - nv50_disp_intr_unk20_0(priv, head); - } - for (head = 0; head < priv->head.nr; head++) { - if (!(super & (0x00000200 << head))) - continue; - nv50_disp_intr_unk20_1(priv, head); - } - for (head = 0; head < priv->head.nr; head++) { - if (!(super & (0x00000080 << head))) - continue; - nv50_disp_intr_unk20_2(priv, head); - } - } else - if (priv->super & 0x00000040) { - for (head = 0; head < priv->head.nr; head++) { - if (!(super & (0x00000080 << head))) - continue; - nv50_disp_intr_unk40_0(priv, head); - } - } - - nv_wr32(priv, 0x610030, 0x80000000); + if (intr1 & 0x00000010) + nv50_disp_intr_unk10(priv, super); + if (intr1 & 0x00000020) + nv50_disp_intr_unk20(priv, super); + if (intr1 & 0x00000040) + nv50_disp_intr_unk40(priv, super); } void @@ -1261,21 +1201,19 @@ nv50_disp_intr(struct nouveau_subdev *subdev) } if (intr1 & 0x00000004) { - nouveau_event_trigger(priv->base.vblank, 0); + nv50_disp_intr_vblank(priv, 0); nv_wr32(priv, 0x610024, 0x00000004); intr1 &= ~0x00000004; } if (intr1 & 0x00000008) { - nouveau_event_trigger(priv->base.vblank, 1); + nv50_disp_intr_vblank(priv, 1); nv_wr32(priv, 0x610024, 0x00000008); intr1 &= ~0x00000008; } if (intr1 & 0x00000070) { - priv->super = (intr1 & 0x00000070); - schedule_work(&priv->supervisor); - nv_wr32(priv, 0x610024, priv->super); + nv50_disp_intr_super(priv, intr1); intr1 &= ~0x00000070; } } @@ -1288,7 +1226,7 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv50_disp_priv *priv; int ret; - ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP", + ret = nouveau_disp_create(parent, engine, oclass, "PDISP", "display", &priv); *pobject = nv_object(priv); if (ret) @@ -1297,17 +1235,16 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nv50_disp_base_oclass; nv_engine(priv)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; - INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); priv->sclass = nv50_disp_sclass; priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 2; - priv->pior.nr = 3; priv->dac.power = nv50_dac_power; priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; - priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; + + INIT_LIST_HEAD(&priv->base.vblank.list); + spin_lock_init(&priv->base.vblank.lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index 1ae6ceb56704..a6bb931450f1 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h @@ -3,22 +3,16 @@ #include #include -#include #include -#include #include #include -#include "dport.h" +struct dcb_output; struct nv50_disp_priv { struct nouveau_disp base; struct nouveau_oclass *sclass; - - struct work_struct supervisor; - u32 super; - struct { int nr; } head; @@ -32,15 +26,23 @@ struct nv50_disp_priv { int (*power)(struct nv50_disp_priv *, int sor, u32 data); int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32); int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32); + int (*dp_train_init)(struct nv50_disp_priv *, int sor, int link, + int head, u16 type, u16 mask, u32 data, + struct dcb_output *); + int (*dp_train_fini)(struct nv50_disp_priv *, int sor, int link, + int head, u16 type, u16 mask, u32 data, + struct dcb_output *); + int (*dp_train)(struct nv50_disp_priv *, int sor, int link, + u16 type, u16 mask, u32 data, + struct dcb_output *); + int (*dp_lnkctl)(struct nv50_disp_priv *, int sor, int link, + int head, u16 type, u16 mask, u32 data, + struct dcb_output *); + int (*dp_drvctl)(struct nv50_disp_priv *, int sor, int link, + int lane, u16 type, u16 mask, u32 data, + struct dcb_output *); u32 lvdsconf; - const struct nouveau_dp_func *dp; } sor; - struct { - int nr; - int (*power)(struct nv50_disp_priv *, int ext, u32 data); - u8 type[3]; - const struct nouveau_dp_func *dp; - } pior; }; #define DAC_MTHD(n) (n), (n) + 0x03 @@ -79,11 +81,6 @@ int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, int nvd0_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, struct dcb_output *); -#define PIOR_MTHD(n) (n), (n) + 0x03 - -int nv50_pior_mthd(struct nouveau_object *, u32, void *, u32); -int nv50_pior_power(struct nv50_disp_priv *, int, u32); - struct nv50_disp_base { struct nouveau_parent base; struct nouveau_ramht *ramht; @@ -127,7 +124,6 @@ extern struct nouveau_ofuncs nv50_disp_oimm_ofuncs; extern struct nouveau_ofuncs nv50_disp_curs_ofuncs; extern struct nouveau_ofuncs nv50_disp_base_ofuncs; extern struct nouveau_oclass nv50_disp_cclass; -void nv50_disp_intr_supervisor(struct work_struct *); void nv50_disp_intr(struct nouveau_subdev *); extern struct nouveau_omthds nv84_disp_base_omthds[]; @@ -141,7 +137,6 @@ extern struct nouveau_ofuncs nvd0_disp_oimm_ofuncs; extern struct nouveau_ofuncs nvd0_disp_curs_ofuncs; extern struct nouveau_ofuncs nvd0_disp_base_ofuncs; extern struct nouveau_oclass nvd0_disp_cclass; -void nvd0_disp_intr_supervisor(struct work_struct *); void nvd0_disp_intr(struct nouveau_subdev *); #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index d8c74c0883a1..fc84eacdfbec 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -46,9 +46,6 @@ nv84_disp_base_omthds[] = { { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; @@ -66,7 +63,7 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv50_disp_priv *priv; int ret; - ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP", + ret = nouveau_disp_create(parent, engine, oclass, "PDISP", "display", &priv); *pobject = nv_object(priv); if (ret) @@ -75,18 +72,17 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nv84_disp_base_oclass; nv_engine(priv)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; - INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); priv->sclass = nv84_disp_sclass; priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 2; - priv->pior.nr = 3; priv->dac.power = nv50_dac_power; priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; priv->sor.hdmi = nv84_hdmi_ctrl; - priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; + + INIT_LIST_HEAD(&priv->base.vblank.list); + spin_lock_init(&priv->base.vblank.lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index a66f949c1f84..ba9dfd4669a2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -44,11 +44,14 @@ nv94_disp_base_omthds[] = { { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(1)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(2)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(3)), nv50_sor_mthd }, { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; @@ -66,7 +69,7 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv50_disp_priv *priv; int ret; - ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP", + ret = nouveau_disp_create(parent, engine, oclass, "PDISP", "display", &priv); *pobject = nv_object(priv); if (ret) @@ -75,19 +78,22 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nv94_disp_base_oclass; nv_engine(priv)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; - INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); priv->sclass = nv94_disp_sclass; priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 4; - priv->pior.nr = 3; priv->dac.power = nv50_dac_power; priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; priv->sor.hdmi = nv84_hdmi_ctrl; - priv->sor.dp = &nv94_sor_dp_func; - priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; + priv->sor.dp_train = nv94_sor_dp_train; + priv->sor.dp_train_init = nv94_sor_dp_train_init; + priv->sor.dp_train_fini = nv94_sor_dp_train_fini; + priv->sor.dp_lnkctl = nv94_sor_dp_lnkctl; + priv->sor.dp_drvctl = nv94_sor_dp_drvctl; + + INIT_LIST_HEAD(&priv->base.vblank.list); + spin_lock_init(&priv->base.vblank.lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c index 6cf8eefac368..5d63902cdeda 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c @@ -53,7 +53,7 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv50_disp_priv *priv; int ret; - ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP", + ret = nouveau_disp_create(parent, engine, oclass, "PDISP", "display", &priv); *pobject = nv_object(priv); if (ret) @@ -62,18 +62,17 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nva0_disp_base_oclass; nv_engine(priv)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; - INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); priv->sclass = nva0_disp_sclass; priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 2; - priv->pior.nr = 3; priv->dac.power = nv50_dac_power; priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; priv->sor.hdmi = nv84_hdmi_ctrl; - priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; + + INIT_LIST_HEAD(&priv->base.vblank.list); + spin_lock_init(&priv->base.vblank.lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index b75413169eae..e9192ca389fa 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -45,11 +45,14 @@ nva3_disp_base_omthds[] = { { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(1)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(2)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(3)), nv50_sor_mthd }, { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; @@ -67,7 +70,7 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv50_disp_priv *priv; int ret; - ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP", + ret = nouveau_disp_create(parent, engine, oclass, "PDISP", "display", &priv); *pobject = nv_object(priv); if (ret) @@ -76,20 +79,23 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nva3_disp_base_oclass; nv_engine(priv)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nv50_disp_intr; - INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); priv->sclass = nva3_disp_sclass; priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 4; - priv->pior.nr = 3; priv->dac.power = nv50_dac_power; priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; priv->sor.hda_eld = nva3_hda_eld; priv->sor.hdmi = nva3_hdmi_ctrl; - priv->sor.dp = &nv94_sor_dp_func; - priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; + priv->sor.dp_train = nv94_sor_dp_train; + priv->sor.dp_train_init = nv94_sor_dp_train_init; + priv->sor.dp_train_fini = nv94_sor_dp_train_fini; + priv->sor.dp_lnkctl = nv94_sor_dp_lnkctl; + priv->sor.dp_drvctl = nv94_sor_dp_drvctl; + + INIT_LIST_HEAD(&priv->base.vblank.list); + spin_lock_init(&priv->base.vblank.lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index 788dd34ccb54..9e38ebff5fb3 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -27,10 +27,12 @@ #include #include +#include #include #include #include +#include #include #include @@ -228,7 +230,7 @@ nvd0_disp_sync_ctor(struct nouveau_object *parent, struct nv50_disp_dmac *dmac; int ret; - if (size < sizeof(*args) || args->head >= priv->head.nr) + if (size < sizeof(*data) || args->head >= priv->head.nr) return -EINVAL; ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, @@ -268,7 +270,7 @@ nvd0_disp_ovly_ctor(struct nouveau_object *parent, struct nv50_disp_dmac *dmac; int ret; - if (size < sizeof(*args) || args->head >= priv->head.nr) + if (size < sizeof(*data) || args->head >= priv->head.nr) return -EINVAL; ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, @@ -441,18 +443,6 @@ nvd0_disp_curs_ofuncs = { * Base display object ******************************************************************************/ -static void -nvd0_disp_base_vblank_enable(struct nouveau_event *event, int head) -{ - nv_mask(event->priv, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000001); -} - -static void -nvd0_disp_base_vblank_disable(struct nouveau_event *event, int head) -{ - nv_mask(event->priv, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000000); -} - static int nvd0_disp_base_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -469,10 +459,6 @@ nvd0_disp_base_ctor(struct nouveau_object *parent, if (ret) return ret; - priv->base.vblank->priv = priv; - priv->base.vblank->enable = nvd0_disp_base_vblank_enable; - priv->base.vblank->disable = nvd0_disp_base_vblank_disable; - return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht); } @@ -623,24 +609,13 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, } static bool -exec_script(struct nv50_disp_priv *priv, int head, int id) +exec_script(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, int id) { struct nouveau_bios *bios = nouveau_bios(priv); struct nvbios_outp info; struct dcb_output dcb; u8 ver, hdr, cnt, len; - u32 ctrl = 0x00000000; u16 data; - int outp; - - for (outp = 0; !(ctrl & (1 << head)) && outp < 8; outp++) { - ctrl = nv_rd32(priv, 0x640180 + (outp * 0x20)); - if (ctrl & (1 << head)) - break; - } - - if (outp == 8) - return false; data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); if (data) { @@ -660,31 +635,21 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) } static u32 -exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, - u32 pclk, struct dcb_output *dcb) +exec_clkcmp(struct nv50_disp_priv *priv, int head, int outp, + u32 ctrl, int id, u32 pclk) { struct nouveau_bios *bios = nouveau_bios(priv); struct nvbios_outp info1; struct nvbios_ocfg info2; + struct dcb_output dcb; u8 ver, hdr, cnt, len; - u32 ctrl = 0x00000000; - u32 data, conf = ~0; - int outp; + u16 data, conf; - for (outp = 0; !(ctrl & (1 << head)) && outp < 8; outp++) { - ctrl = nv_rd32(priv, 0x660180 + (outp * 0x20)); - if (ctrl & (1 << head)) - break; - } - - if (outp == 8) - return false; - - data = exec_lookup(priv, head, outp, ctrl, dcb, &ver, &hdr, &cnt, &len, &info1); + data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info1); if (data == 0x0000) - return conf; + return false; - switch (dcb->type) { + switch (dcb.type) { case DCB_OUTPUT_TMDS: conf = (ctrl & 0x00000f00) >> 8; if (pclk >= 165000) @@ -703,52 +668,46 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, } data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2); - if (data && id < 0xff) { + if (data) { data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); if (data) { struct nvbios_init init = { .subdev = nv_subdev(priv), .bios = bios, .offset = data, - .outp = dcb, + .outp = &dcb, .crtc = head, .execute = 1, }; - nvbios_exec(&init); + if (nvbios_exec(&init)) + return 0x0000; + return conf; } } - return conf; + return 0x0000; } static void -nvd0_disp_intr_unk1_0(struct nv50_disp_priv *priv, int head) +nvd0_display_unk1_handler(struct nv50_disp_priv *priv, u32 head, u32 mask) { - exec_script(priv, head, 1); -} + int i; -static void -nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head) -{ - exec_script(priv, head, 2); -} + for (i = 0; mask && i < 8; i++) { + u32 mcc = nv_rd32(priv, 0x640180 + (i * 0x20)); + if (mcc & (1 << head)) + exec_script(priv, head, i, mcc, 1); + } -static void -nvd0_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head) -{ - struct nouveau_clock *clk = nouveau_clock(priv); - u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; - if (pclk) - clk->pll_set(clk, PLL_VPLL0 + head, pclk); - nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000); + nv_wr32(priv, 0x6101d4, 0x00000000); + nv_wr32(priv, 0x6109d4, 0x00000000); + nv_wr32(priv, 0x6101d0, 0x80000000); } static void -nvd0_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head, - struct dcb_output *outp) +nvd0_display_unk2_calc_tu(struct nv50_disp_priv *priv, int head, int or) { - const int or = ffs(outp->or) - 1; const u32 ctrl = nv_rd32(priv, 0x660200 + (or * 0x020)); const u32 conf = nv_rd32(priv, 0x660404 + (head * 0x300)); const u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; @@ -791,104 +750,107 @@ nvd0_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head, } static void -nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head) +nvd0_display_unk2_handler(struct nv50_disp_priv *priv, u32 head, u32 mask) { - struct dcb_output outp; - u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; - u32 conf = exec_clkcmp(priv, head, 0xff, pclk, &outp); - if (conf != ~0) { - u32 addr, data; - - if (outp.type == DCB_OUTPUT_DP) { - u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300)); - switch ((sync & 0x000003c0) >> 6) { - case 6: pclk = pclk * 30 / 8; break; - case 5: pclk = pclk * 24 / 8; break; - case 2: - default: - pclk = pclk * 18 / 8; - break; - } + u32 pclk; + int i; - nouveau_dp_train(&priv->base, priv->sor.dp, - &outp, head, pclk); - } + for (i = 0; mask && i < 8; i++) { + u32 mcc = nv_rd32(priv, 0x640180 + (i * 0x20)); + if (mcc & (1 << head)) + exec_script(priv, head, i, mcc, 2); + } - exec_clkcmp(priv, head, 0, pclk, &outp); + pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; + nv_debug(priv, "head %d pclk %d mask 0x%08x\n", head, pclk, mask); + if (pclk && (mask & 0x00010000)) { + struct nouveau_clock *clk = nouveau_clock(priv); + clk->pll_set(clk, PLL_VPLL0 + head, pclk); + } - if (outp.type == DCB_OUTPUT_ANALOG) { - addr = 0x612280 + (ffs(outp.or) - 1) * 0x800; - data = 0x00000000; - } else { - if (outp.type == DCB_OUTPUT_DP) - nvd0_disp_intr_unk2_2_tu(priv, head, &outp); - addr = 0x612300 + (ffs(outp.or) - 1) * 0x800; - data = (conf & 0x0100) ? 0x00000101 : 0x00000000; - } + nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000); - nv_mask(priv, addr, 0x00000707, data); + for (i = 0; mask && i < 8; i++) { + u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20)), cfg; + if (mcp & (1 << head)) { + if ((cfg = exec_clkcmp(priv, head, i, mcp, 0, pclk))) { + u32 addr, mask, data = 0x00000000; + if (i < 4) { + addr = 0x612280 + ((i - 0) * 0x800); + mask = 0xffffffff; + } else { + switch (mcp & 0x00000f00) { + case 0x00000800: + case 0x00000900: + nvd0_display_unk2_calc_tu(priv, head, i - 4); + break; + default: + break; + } + + addr = 0x612300 + ((i - 4) * 0x800); + mask = 0x00000707; + if (cfg & 0x00000100) + data = 0x00000101; + } + nv_mask(priv, addr, mask, data); + } + break; + } } + + nv_wr32(priv, 0x6101d4, 0x00000000); + nv_wr32(priv, 0x6109d4, 0x00000000); + nv_wr32(priv, 0x6101d0, 0x80000000); } static void -nvd0_disp_intr_unk4_0(struct nv50_disp_priv *priv, int head) +nvd0_display_unk4_handler(struct nv50_disp_priv *priv, u32 head, u32 mask) { - struct dcb_output outp; - u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; - exec_clkcmp(priv, head, 1, pclk, &outp); -} + int pclk, i; -void -nvd0_disp_intr_supervisor(struct work_struct *work) -{ - struct nv50_disp_priv *priv = - container_of(work, struct nv50_disp_priv, supervisor); - u32 mask[4]; - int head; - - nv_debug(priv, "supervisor %08x\n", priv->super); - for (head = 0; head < priv->head.nr; head++) { - mask[head] = nv_rd32(priv, 0x6101d4 + (head * 0x800)); - nv_debug(priv, "head %d: 0x%08x\n", head, mask[head]); - } + pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; - if (priv->super & 0x00000001) { - for (head = 0; head < priv->head.nr; head++) { - if (!(mask[head] & 0x00001000)) - continue; - nvd0_disp_intr_unk1_0(priv, head); - } - } else - if (priv->super & 0x00000002) { - for (head = 0; head < priv->head.nr; head++) { - if (!(mask[head] & 0x00001000)) - continue; - nvd0_disp_intr_unk2_0(priv, head); - } - for (head = 0; head < priv->head.nr; head++) { - if (!(mask[head] & 0x00010000)) - continue; - nvd0_disp_intr_unk2_1(priv, head); - } - for (head = 0; head < priv->head.nr; head++) { - if (!(mask[head] & 0x00001000)) - continue; - nvd0_disp_intr_unk2_2(priv, head); - } - } else - if (priv->super & 0x00000004) { - for (head = 0; head < priv->head.nr; head++) { - if (!(mask[head] & 0x00001000)) - continue; - nvd0_disp_intr_unk4_0(priv, head); - } + for (i = 0; mask && i < 8; i++) { + u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20)); + if (mcp & (1 << head)) + exec_clkcmp(priv, head, i, mcp, 1, pclk); } - for (head = 0; head < priv->head.nr; head++) - nv_wr32(priv, 0x6101d4 + (head * 0x800), 0x00000000); + nv_wr32(priv, 0x6101d4, 0x00000000); + nv_wr32(priv, 0x6109d4, 0x00000000); nv_wr32(priv, 0x6101d0, 0x80000000); } +static void +nvd0_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) +{ + struct nouveau_bar *bar = nouveau_bar(priv); + struct nouveau_disp *disp = &priv->base; + struct nouveau_software_chan *chan, *temp; + unsigned long flags; + + spin_lock_irqsave(&disp->vblank.lock, flags); + list_for_each_entry_safe(chan, temp, &disp->vblank.list, vblank.head) { + if (chan->vblank.crtc != crtc) + continue; + + nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); + bar->flush(bar); + nv_wr32(priv, 0x06000c, upper_32_bits(chan->vblank.offset)); + nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset)); + nv_wr32(priv, 0x060014, chan->vblank.value); + + list_del(&chan->vblank.head); + if (disp->vblank.put) + disp->vblank.put(disp->vblank.data, crtc); + } + spin_unlock_irqrestore(&disp->vblank.lock, flags); + + if (disp->vblank.notify) + disp->vblank.notify(disp->vblank.data, crtc); +} + void nvd0_disp_intr(struct nouveau_subdev *subdev) { @@ -922,11 +884,27 @@ nvd0_disp_intr(struct nouveau_subdev *subdev) if (intr & 0x00100000) { u32 stat = nv_rd32(priv, 0x6100ac); - if (stat & 0x00000007) { - priv->super = (stat & 0x00000007); - schedule_work(&priv->supervisor); - nv_wr32(priv, 0x6100ac, priv->super); - stat &= ~0x00000007; + u32 mask = 0, crtc = ~0; + + while (!mask && ++crtc < priv->head.nr) + mask = nv_rd32(priv, 0x6101d4 + (crtc * 0x800)); + + if (stat & 0x00000001) { + nv_wr32(priv, 0x6100ac, 0x00000001); + nvd0_display_unk1_handler(priv, crtc, mask); + stat &= ~0x00000001; + } + + if (stat & 0x00000002) { + nv_wr32(priv, 0x6100ac, 0x00000002); + nvd0_display_unk2_handler(priv, crtc, mask); + stat &= ~0x00000002; + } + + if (stat & 0x00000004) { + nv_wr32(priv, 0x6100ac, 0x00000004); + nvd0_display_unk4_handler(priv, crtc, mask); + stat &= ~0x00000004; } if (stat) { @@ -942,7 +920,7 @@ nvd0_disp_intr(struct nouveau_subdev *subdev) if (mask & intr) { u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800)); if (stat & 0x00000001) - nouveau_event_trigger(priv->base.vblank, i); + nvd0_disp_intr_vblank(priv, i); nv_mask(priv, 0x6100bc + (i * 0x800), 0, 0); nv_rd32(priv, 0x6100c0 + (i * 0x800)); } @@ -955,11 +933,10 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_object **pobject) { struct nv50_disp_priv *priv; - int heads = nv_rd32(parent, 0x022448); int ret; - ret = nouveau_disp_create(parent, engine, oclass, heads, - "PDISP", "display", &priv); + ret = nouveau_disp_create(parent, engine, oclass, "PDISP", + "display", &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -967,9 +944,8 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nvd0_disp_base_oclass; nv_engine(priv)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nvd0_disp_intr; - INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor); priv->sclass = nvd0_disp_sclass; - priv->head.nr = heads; + priv->head.nr = nv_rd32(priv, 0x022448); priv->dac.nr = 3; priv->sor.nr = 4; priv->dac.power = nv50_dac_power; @@ -977,7 +953,14 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hda_eld = nvd0_hda_eld; priv->sor.hdmi = nvd0_hdmi_ctrl; - priv->sor.dp = &nvd0_sor_dp_func; + priv->sor.dp_train = nvd0_sor_dp_train; + priv->sor.dp_train_init = nv94_sor_dp_train_init; + priv->sor.dp_train_fini = nv94_sor_dp_train_fini; + priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; + priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; + + INIT_LIST_HEAD(&priv->base.vblank.list); + spin_lock_init(&priv->base.vblank.lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c index 20725b363d58..259537c4587e 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c @@ -51,11 +51,10 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_object **pobject) { struct nv50_disp_priv *priv; - int heads = nv_rd32(parent, 0x022448); int ret; - ret = nouveau_disp_create(parent, engine, oclass, heads, - "PDISP", "display", &priv); + ret = nouveau_disp_create(parent, engine, oclass, "PDISP", + "display", &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -63,9 +62,8 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nve0_disp_base_oclass; nv_engine(priv)->cclass = &nv50_disp_cclass; nv_subdev(priv)->intr = nvd0_disp_intr; - INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor); priv->sclass = nve0_disp_sclass; - priv->head.nr = heads; + priv->head.nr = nv_rd32(priv, 0x022448); priv->dac.nr = 3; priv->sor.nr = 4; priv->dac.power = nv50_dac_power; @@ -73,7 +71,14 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hda_eld = nvd0_hda_eld; priv->sor.hdmi = nvd0_hdmi_ctrl; - priv->sor.dp = &nvd0_sor_dp_func; + priv->sor.dp_train = nvd0_sor_dp_train; + priv->sor.dp_train_init = nv94_sor_dp_train_init; + priv->sor.dp_train_fini = nv94_sor_dp_train_fini; + priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; + priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; + + INIT_LIST_HEAD(&priv->base.vblank.list); + spin_lock_init(&priv->base.vblank.lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c deleted file mode 100644 index 2c8ce351b52d..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c +++ /dev/null @@ -1,140 +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 -#include - -#include -#include -#include -#include - -#include "nv50.h" - -/****************************************************************************** - * DisplayPort - *****************************************************************************/ -static struct nouveau_i2c_port * -nv50_pior_dp_find(struct nouveau_disp *disp, struct dcb_output *outp) -{ - struct nouveau_i2c *i2c = nouveau_i2c(disp); - return i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(outp->extdev)); -} - -static int -nv50_pior_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int pattern) -{ - struct nouveau_i2c_port *port; - int ret = -EINVAL; - - port = nv50_pior_dp_find(disp, outp); - if (port) { - if (port->func->pattern) - ret = port->func->pattern(port, pattern); - else - ret = 0; - } - - return ret; -} - -static int -nv50_pior_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane_nr, int link_bw, bool enh) -{ - struct nouveau_i2c_port *port; - int ret = -EINVAL; - - port = nv50_pior_dp_find(disp, outp); - if (port && port->func->lnk_ctl) - ret = port->func->lnk_ctl(port, lane_nr, link_bw, enh); - - return ret; -} - -static int -nv50_pior_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane, int vsw, int pre) -{ - struct nouveau_i2c_port *port; - int ret = -EINVAL; - - port = nv50_pior_dp_find(disp, outp); - if (port) { - if (port->func->drv_ctl) - ret = port->func->drv_ctl(port, lane, vsw, pre); - else - ret = 0; - } - - return ret; -} - -const struct nouveau_dp_func -nv50_pior_dp_func = { - .pattern = nv50_pior_dp_pattern, - .lnk_ctl = nv50_pior_dp_lnk_ctl, - .drv_ctl = nv50_pior_dp_drv_ctl, -}; - -/****************************************************************************** - * General PIOR handling - *****************************************************************************/ -int -nv50_pior_power(struct nv50_disp_priv *priv, int or, u32 data) -{ - const u32 stat = data & NV50_DISP_PIOR_PWR_STATE; - const u32 soff = (or * 0x800); - nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); - nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | stat); - nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); - return 0; -} - -int -nv50_pior_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) -{ - struct nv50_disp_priv *priv = (void *)object->engine; - const u8 type = (mthd & NV50_DISP_PIOR_MTHD_TYPE) >> 12; - const u8 or = (mthd & NV50_DISP_PIOR_MTHD_OR); - u32 *data = args; - int ret; - - if (size < sizeof(u32)) - return -EINVAL; - - mthd &= ~NV50_DISP_PIOR_MTHD_TYPE; - mthd &= ~NV50_DISP_PIOR_MTHD_OR; - switch (mthd) { - case NV50_DISP_PIOR_PWR: - ret = priv->pior.power(priv, or, data[0]); - priv->pior.type[or] = type; - break; - default: - return -EINVAL; - } - - return ret; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index ab1e918469a8..39b6b67732d0 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c @@ -79,6 +79,31 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID; ret = 0; break; + case NV94_DISP_SOR_DP_TRAIN: + switch (data & NV94_DISP_SOR_DP_TRAIN_OP) { + case NV94_DISP_SOR_DP_TRAIN_OP_PATTERN: + ret = priv->sor.dp_train(priv, or, link, type, mask, data, &outp); + break; + case NV94_DISP_SOR_DP_TRAIN_OP_INIT: + ret = priv->sor.dp_train_init(priv, or, link, head, type, mask, data, &outp); + break; + case NV94_DISP_SOR_DP_TRAIN_OP_FINI: + ret = priv->sor.dp_train_fini(priv, or, link, head, type, mask, data, &outp); + break; + default: + break; + } + break; + case NV94_DISP_SOR_DP_LNKCTL: + ret = priv->sor.dp_lnkctl(priv, or, link, head, type, mask, data, &outp); + break; + case NV94_DISP_SOR_DP_DRVCTL(0): + case NV94_DISP_SOR_DP_DRVCTL(1): + case NV94_DISP_SOR_DP_DRVCTL(2): + case NV94_DISP_SOR_DP_DRVCTL(3): + ret = priv->sor.dp_drvctl(priv, or, link, (mthd & 0xc0) >> 6, + type, mask, data, &outp); + break; default: BUG_ON(1); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c index 7ec4ee83fb64..f6edd009762e 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c @@ -32,18 +32,6 @@ #include "nv50.h" -static inline u32 -nv94_sor_soff(struct dcb_output *outp) -{ - return (ffs(outp->or) - 1) * 0x800; -} - -static inline u32 -nv94_sor_loff(struct dcb_output *outp) -{ - return nv94_sor_soff(outp) + !(outp->sorconf.link & 1) * 0x80; -} - static inline u32 nv94_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane) { @@ -54,32 +42,115 @@ nv94_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane) return nv94[lane]; } -static int -nv94_sor_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int pattern) +int +nv94_sor_dp_train_init(struct nv50_disp_priv *priv, int or, int link, int head, + u16 type, u16 mask, u32 data, struct dcb_output *dcbo) +{ + struct nouveau_bios *bios = nouveau_bios(priv); + struct nvbios_dpout info; + u8 ver, hdr, cnt, len; + u16 outp; + + outp = nvbios_dpout_match(bios, type, mask, &ver, &hdr, &cnt, &len, &info); + if (outp) { + struct nvbios_init init = { + .subdev = nv_subdev(priv), + .bios = bios, + .outp = dcbo, + .crtc = head, + .execute = 1, + }; + + if (data & NV94_DISP_SOR_DP_TRAIN_INIT_SPREAD_ON) + init.offset = info.script[2]; + else + init.offset = info.script[3]; + nvbios_exec(&init); + + init.offset = info.script[0]; + nvbios_exec(&init); + } + + return 0; +} + +int +nv94_sor_dp_train_fini(struct nv50_disp_priv *priv, int or, int link, int head, + u16 type, u16 mask, u32 data, struct dcb_output *dcbo) { - struct nv50_disp_priv *priv = (void *)disp; - const u32 loff = nv94_sor_loff(outp); - nv_mask(priv, 0x61c10c + loff, 0x0f000000, pattern << 24); + struct nouveau_bios *bios = nouveau_bios(priv); + struct nvbios_dpout info; + u8 ver, hdr, cnt, len; + u16 outp; + + outp = nvbios_dpout_match(bios, type, mask, &ver, &hdr, &cnt, &len, &info); + if (outp) { + struct nvbios_init init = { + .subdev = nv_subdev(priv), + .bios = bios, + .offset = info.script[1], + .outp = dcbo, + .crtc = head, + .execute = 1, + }; + + nvbios_exec(&init); + } + + return 0; +} + +int +nv94_sor_dp_train(struct nv50_disp_priv *priv, int or, int link, + u16 type, u16 mask, u32 data, struct dcb_output *info) +{ + const u32 loff = (or * 0x800) + (link * 0x80); + const u32 patt = (data & NV94_DISP_SOR_DP_TRAIN_PATTERN); + nv_mask(priv, 0x61c10c + loff, 0x0f000000, patt << 24); return 0; } -static int -nv94_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int link_nr, int link_bw, bool enh_frame) +int +nv94_sor_dp_lnkctl(struct nv50_disp_priv *priv, int or, int link, int head, + u16 type, u16 mask, u32 data, struct dcb_output *dcbo) { - struct nv50_disp_priv *priv = (void *)disp; - const u32 soff = nv94_sor_soff(outp); - const u32 loff = nv94_sor_loff(outp); + struct nouveau_bios *bios = nouveau_bios(priv); + const u32 loff = (or * 0x800) + (link * 0x80); + const u32 soff = (or * 0x800); + u16 link_bw = (data & NV94_DISP_SOR_DP_LNKCTL_WIDTH) >> 8; + u8 link_nr = (data & NV94_DISP_SOR_DP_LNKCTL_COUNT); u32 dpctrl = 0x00000000; u32 clksor = 0x00000000; - u32 lane = 0; + u32 outp, lane = 0; + u8 ver, hdr, cnt, len; + struct nvbios_dpout info; int i; + /* -> 10Khz units */ + link_bw *= 2700; + + outp = nvbios_dpout_match(bios, type, mask, &ver, &hdr, &cnt, &len, &info); + if (outp && info.lnkcmp) { + struct nvbios_init init = { + .subdev = nv_subdev(priv), + .bios = bios, + .offset = 0x0000, + .outp = dcbo, + .crtc = head, + .execute = 1, + }; + + while (link_bw < nv_ro16(bios, info.lnkcmp)) + info.lnkcmp += 4; + init.offset = nv_ro16(bios, info.lnkcmp + 2); + + nvbios_exec(&init); + } + dpctrl |= ((1 << link_nr) - 1) << 16; - if (enh_frame) + if (data & NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH) dpctrl |= 0x00004000; - if (link_bw > 0x06) + if (link_bw > 16200) clksor |= 0x00040000; for (i = 0; i < link_nr; i++) @@ -91,25 +162,24 @@ nv94_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, return 0; } -static int -nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane, int swing, int preem) +int +nv94_sor_dp_drvctl(struct nv50_disp_priv *priv, int or, int link, int lane, + u16 type, u16 mask, u32 data, struct dcb_output *dcbo) { - struct nouveau_bios *bios = nouveau_bios(disp); - struct nv50_disp_priv *priv = (void *)disp; - const u32 loff = nv94_sor_loff(outp); + struct nouveau_bios *bios = nouveau_bios(priv); + const u32 loff = (or * 0x800) + (link * 0x80); + const u8 swing = (data & NV94_DISP_SOR_DP_DRVCTL_VS) >> 8; + const u8 preem = (data & NV94_DISP_SOR_DP_DRVCTL_PE); u32 addr, shift = nv94_sor_dp_lane_map(priv, lane); u8 ver, hdr, cnt, len; - struct nvbios_dpout info; + struct nvbios_dpout outp; struct nvbios_dpcfg ocfg; - addr = nvbios_dpout_match(bios, outp->hasht, outp->hashm, - &ver, &hdr, &cnt, &len, &info); + addr = nvbios_dpout_match(bios, type, mask, &ver, &hdr, &cnt, &len, &outp); if (!addr) return -ENODEV; - addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem, - &ver, &hdr, &cnt, &len, &ocfg); + addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem, &ver, &hdr, &cnt, &len, &ocfg); if (!addr) return -EINVAL; @@ -118,10 +188,3 @@ nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, nv_mask(priv, 0x61c130 + loff, 0x0000ff00, ocfg.unk << 8); return 0; } - -const struct nouveau_dp_func -nv94_sor_dp_func = { - .pattern = nv94_sor_dp_pattern, - .lnk_ctl = nv94_sor_dp_lnk_ctl, - .drv_ctl = nv94_sor_dp_drv_ctl, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c index 9e1d435d7282..c37ce7e29f5d 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c @@ -32,18 +32,6 @@ #include "nv50.h" -static inline u32 -nvd0_sor_soff(struct dcb_output *outp) -{ - return (ffs(outp->or) - 1) * 0x800; -} - -static inline u32 -nvd0_sor_loff(struct dcb_output *outp) -{ - return nvd0_sor_soff(outp) + !(outp->sorconf.link & 1) * 0x80; -} - static inline u32 nvd0_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane) { @@ -51,31 +39,53 @@ nvd0_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane) return nvd0[lane]; } -static int -nvd0_sor_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int pattern) +int +nvd0_sor_dp_train(struct nv50_disp_priv *priv, int or, int link, + u16 type, u16 mask, u32 data, struct dcb_output *info) { - struct nv50_disp_priv *priv = (void *)disp; - const u32 loff = nvd0_sor_loff(outp); - nv_mask(priv, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern); + const u32 loff = (or * 0x800) + (link * 0x80); + const u32 patt = (data & NV94_DISP_SOR_DP_TRAIN_PATTERN); + nv_mask(priv, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * patt); return 0; } -static int -nvd0_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int link_nr, int link_bw, bool enh_frame) +int +nvd0_sor_dp_lnkctl(struct nv50_disp_priv *priv, int or, int link, int head, + u16 type, u16 mask, u32 data, struct dcb_output *dcbo) { - struct nv50_disp_priv *priv = (void *)disp; - const u32 soff = nvd0_sor_soff(outp); - const u32 loff = nvd0_sor_loff(outp); + struct nouveau_bios *bios = nouveau_bios(priv); + const u32 loff = (or * 0x800) + (link * 0x80); + const u32 soff = (or * 0x800); + const u8 link_bw = (data & NV94_DISP_SOR_DP_LNKCTL_WIDTH) >> 8; + const u8 link_nr = (data & NV94_DISP_SOR_DP_LNKCTL_COUNT); u32 dpctrl = 0x00000000; u32 clksor = 0x00000000; - u32 lane = 0; + u32 outp, lane = 0; + u8 ver, hdr, cnt, len; + struct nvbios_dpout info; int i; + outp = nvbios_dpout_match(bios, type, mask, &ver, &hdr, &cnt, &len, &info); + if (outp && info.lnkcmp) { + struct nvbios_init init = { + .subdev = nv_subdev(priv), + .bios = bios, + .offset = 0x0000, + .outp = dcbo, + .crtc = head, + .execute = 1, + }; + + while (nv_ro08(bios, info.lnkcmp) < link_bw) + info.lnkcmp += 3; + init.offset = nv_ro16(bios, info.lnkcmp + 1); + + nvbios_exec(&init); + } + clksor |= link_bw << 18; dpctrl |= ((1 << link_nr) - 1) << 16; - if (enh_frame) + if (data & NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH) dpctrl |= 0x00004000; for (i = 0; i < link_nr; i++) @@ -87,25 +97,24 @@ nvd0_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, return 0; } -static int -nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane, int swing, int preem) +int +nvd0_sor_dp_drvctl(struct nv50_disp_priv *priv, int or, int link, int lane, + u16 type, u16 mask, u32 data, struct dcb_output *dcbo) { - struct nouveau_bios *bios = nouveau_bios(disp); - struct nv50_disp_priv *priv = (void *)disp; - const u32 loff = nvd0_sor_loff(outp); + struct nouveau_bios *bios = nouveau_bios(priv); + const u32 loff = (or * 0x800) + (link * 0x80); + const u8 swing = (data & NV94_DISP_SOR_DP_DRVCTL_VS) >> 8; + const u8 preem = (data & NV94_DISP_SOR_DP_DRVCTL_PE); u32 addr, shift = nvd0_sor_dp_lane_map(priv, lane); u8 ver, hdr, cnt, len; - struct nvbios_dpout info; + struct nvbios_dpout outp; struct nvbios_dpcfg ocfg; - addr = nvbios_dpout_match(bios, outp->hasht, outp->hashm, - &ver, &hdr, &cnt, &len, &info); + addr = nvbios_dpout_match(bios, type, mask, &ver, &hdr, &cnt, &len, &outp); if (!addr) return -ENODEV; - addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem, - &ver, &hdr, &cnt, &len, &ocfg); + addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem, &ver, &hdr, &cnt, &len, &ocfg); if (!addr) return -EINVAL; @@ -115,10 +124,3 @@ nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, nv_mask(priv, 0x61c13c + loff, 0x00000000, 0x00000000); return 0; } - -const struct nouveau_dp_func -nvd0_sor_dp_func = { - .pattern = nvd0_sor_dp_pattern, - .lnk_ctl = nvd0_sor_dp_lnk_ctl, - .drv_ctl = nvd0_sor_dp_drv_ctl, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index 7341ebe131fa..c2b9db335816 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -22,10 +22,8 @@ * Authors: Ben Skeggs */ -#include #include #include -#include #include #include @@ -148,25 +146,10 @@ nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object) return -1; } -const char * -nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid) -{ - struct nouveau_fifo_chan *chan = NULL; - unsigned long flags; - - spin_lock_irqsave(&fifo->lock, flags); - if (chid >= fifo->min && chid <= fifo->max) - chan = (void *)fifo->channel[chid]; - spin_unlock_irqrestore(&fifo->lock, flags); - - return nouveau_client_name(chan); -} - void nouveau_fifo_destroy(struct nouveau_fifo *priv) { kfree(priv->channel); - nouveau_event_destroy(&priv->uevent); nouveau_engine_destroy(&priv->base); } @@ -191,10 +174,6 @@ nouveau_fifo_create_(struct nouveau_object *parent, if (!priv->channel) return -ENOMEM; - ret = nouveau_event_create(1, &priv->uevent); - if (ret) - return ret; - priv->chid = nouveau_fifo_chid; spin_lock_init(&priv->lock); return 0; diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index f877bd524a92..a47a8548f9e0 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -399,98 +398,6 @@ nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data) return handled; } -static void -nv04_fifo_cache_error(struct nouveau_device *device, - struct nv04_fifo_priv *priv, u32 chid, u32 get) -{ - u32 mthd, data; - int ptr; - - /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before wrapping on my - * G80 chips, but CACHE1 isn't big enough for this much data.. Tests - * show that it wraps around to the start at GET=0x800.. No clue as to - * why.. - */ - ptr = (get & 0x7ff) >> 2; - - if (device->card_type < NV_40) { - mthd = nv_rd32(priv, NV04_PFIFO_CACHE1_METHOD(ptr)); - data = nv_rd32(priv, NV04_PFIFO_CACHE1_DATA(ptr)); - } else { - mthd = nv_rd32(priv, NV40_PFIFO_CACHE1_METHOD(ptr)); - data = nv_rd32(priv, NV40_PFIFO_CACHE1_DATA(ptr)); - } - - if (!nv04_fifo_swmthd(priv, chid, mthd, data)) { - const char *client_name = - nouveau_client_name_for_fifo_chid(&priv->base, chid); - nv_error(priv, - "CACHE_ERROR - ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n", - chid, client_name, (mthd >> 13) & 7, mthd & 0x1ffc, - data); - } - - nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0); - nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR); - - nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, - nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) & ~1); - nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4); - nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, - nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) | 1); - nv_wr32(priv, NV04_PFIFO_CACHE1_HASH, 0); - - nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, - nv_rd32(priv, NV04_PFIFO_CACHE1_DMA_PUSH) | 1); - nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1); -} - -static void -nv04_fifo_dma_pusher(struct nouveau_device *device, struct nv04_fifo_priv *priv, - u32 chid) -{ - const char *client_name; - u32 dma_get = nv_rd32(priv, 0x003244); - u32 dma_put = nv_rd32(priv, 0x003240); - u32 push = nv_rd32(priv, 0x003220); - u32 state = nv_rd32(priv, 0x003228); - - client_name = nouveau_client_name_for_fifo_chid(&priv->base, chid); - - if (device->card_type == NV_50) { - u32 ho_get = nv_rd32(priv, 0x003328); - u32 ho_put = nv_rd32(priv, 0x003320); - u32 ib_get = nv_rd32(priv, 0x003334); - u32 ib_put = nv_rd32(priv, 0x003330); - - nv_error(priv, - "DMA_PUSHER - ch %d [%s] get 0x%02x%08x put 0x%02x%08x ib_get 0x%08x ib_put 0x%08x state 0x%08x (err: %s) push 0x%08x\n", - chid, client_name, ho_get, dma_get, ho_put, dma_put, - ib_get, ib_put, state, nv_dma_state_err(state), push); - - /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ - nv_wr32(priv, 0x003364, 0x00000000); - if (dma_get != dma_put || ho_get != ho_put) { - nv_wr32(priv, 0x003244, dma_put); - nv_wr32(priv, 0x003328, ho_put); - } else - if (ib_get != ib_put) - nv_wr32(priv, 0x003334, ib_put); - } else { - nv_error(priv, - "DMA_PUSHER - ch %d [%s] get 0x%08x put 0x%08x state 0x%08x (err: %s) push 0x%08x\n", - chid, client_name, dma_get, dma_put, state, - nv_dma_state_err(state), push); - - if (dma_get != dma_put) - nv_wr32(priv, 0x003244, dma_put); - } - - nv_wr32(priv, 0x003228, 0x00000000); - nv_wr32(priv, 0x003220, 0x00000001); - nv_wr32(priv, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); -} - void nv04_fifo_intr(struct nouveau_subdev *subdev) { @@ -509,12 +416,96 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET); if (status & NV_PFIFO_INTR_CACHE_ERROR) { - nv04_fifo_cache_error(device, priv, chid, get); + uint32_t mthd, data; + int ptr; + + /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before + * wrapping on my G80 chips, but CACHE1 isn't big + * enough for this much data.. Tests show that it + * wraps around to the start at GET=0x800.. No clue + * as to why.. + */ + ptr = (get & 0x7ff) >> 2; + + if (device->card_type < NV_40) { + mthd = nv_rd32(priv, + NV04_PFIFO_CACHE1_METHOD(ptr)); + data = nv_rd32(priv, + NV04_PFIFO_CACHE1_DATA(ptr)); + } else { + mthd = nv_rd32(priv, + NV40_PFIFO_CACHE1_METHOD(ptr)); + data = nv_rd32(priv, + NV40_PFIFO_CACHE1_DATA(ptr)); + } + + if (!nv04_fifo_swmthd(priv, chid, mthd, data)) { + nv_error(priv, "CACHE_ERROR - Ch %d/%d " + "Mthd 0x%04x Data 0x%08x\n", + chid, (mthd >> 13) & 7, mthd & 0x1ffc, + data); + } + + nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0); + nv_wr32(priv, NV03_PFIFO_INTR_0, + NV_PFIFO_INTR_CACHE_ERROR); + + nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, + nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) & ~1); + nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4); + nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, + nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) | 1); + nv_wr32(priv, NV04_PFIFO_CACHE1_HASH, 0); + + nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, + nv_rd32(priv, NV04_PFIFO_CACHE1_DMA_PUSH) | 1); + nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1); + status &= ~NV_PFIFO_INTR_CACHE_ERROR; } if (status & NV_PFIFO_INTR_DMA_PUSHER) { - nv04_fifo_dma_pusher(device, priv, chid); + u32 dma_get = nv_rd32(priv, 0x003244); + u32 dma_put = nv_rd32(priv, 0x003240); + u32 push = nv_rd32(priv, 0x003220); + u32 state = nv_rd32(priv, 0x003228); + + if (device->card_type == NV_50) { + u32 ho_get = nv_rd32(priv, 0x003328); + u32 ho_put = nv_rd32(priv, 0x003320); + u32 ib_get = nv_rd32(priv, 0x003334); + u32 ib_put = nv_rd32(priv, 0x003330); + + nv_error(priv, "DMA_PUSHER - Ch %d Get 0x%02x%08x " + "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " + "State 0x%08x (err: %s) Push 0x%08x\n", + chid, ho_get, dma_get, ho_put, + dma_put, ib_get, ib_put, state, + nv_dma_state_err(state), + push); + + /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ + nv_wr32(priv, 0x003364, 0x00000000); + if (dma_get != dma_put || ho_get != ho_put) { + nv_wr32(priv, 0x003244, dma_put); + nv_wr32(priv, 0x003328, ho_put); + } else + if (ib_get != ib_put) { + nv_wr32(priv, 0x003334, ib_put); + } + } else { + nv_error(priv, "DMA_PUSHER - Ch %d Get 0x%08x " + "Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n", + chid, dma_get, dma_put, state, + nv_dma_state_err(state), push); + + if (dma_get != dma_put) + nv_wr32(priv, 0x003244, dma_put); + } + + nv_wr32(priv, 0x003228, 0x00000000); + nv_wr32(priv, 0x003220, 0x00000001); + nv_wr32(priv, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); status &= ~NV_PFIFO_INTR_DMA_PUSHER; } @@ -537,12 +528,6 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) status &= ~0x00000010; nv_wr32(priv, 0x002100, 0x00000010); } - - if (status & 0x40000000) { - nouveau_event_trigger(priv->base.uevent, 0); - nv_wr32(priv, 0x002100, 0x40000000); - status &= ~0x40000000; - } } if (status) { diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index 840af6172788..bd096364f680 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -129,8 +129,7 @@ nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend, /* do the kickoff... */ nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12); if (!nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff)) { - nv_error(priv, "channel %d [%s] unload timeout\n", - chan->base.chid, nouveau_client_name(chan)); + nv_error(priv, "channel %d unload timeout\n", chan->base.chid); if (suspend) ret = -EBUSY; } @@ -481,7 +480,7 @@ nv50_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x002044, 0x01003fff); nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0xbfffffff); + nv_wr32(priv, 0x002140, 0xffffffff); for (i = 0; i < 128; i++) nv_wr32(priv, 0x002600 + (i * 4), 0x00000000); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index 094000e87871..1eb1c512f503 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -101,8 +100,7 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend, done = nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff); nv_wr32(priv, 0x002520, save); if (!done) { - nv_error(priv, "channel %d [%s] unload timeout\n", - chan->base.chid, nouveau_client_name(chan)); + nv_error(priv, "channel %d unload timeout\n", chan->base.chid); if (suspend) return -EBUSY; } @@ -380,20 +378,6 @@ nv84_fifo_cclass = { * PFIFO engine ******************************************************************************/ -static void -nv84_fifo_uevent_enable(struct nouveau_event *event, int index) -{ - struct nv84_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x40000000, 0x40000000); -} - -static void -nv84_fifo_uevent_disable(struct nouveau_event *event, int index) -{ - struct nv84_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x40000000, 0x00000000); -} - static int nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -417,10 +401,6 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nv84_fifo_uevent_enable; - priv->base.uevent->disable = nv84_fifo_uevent_disable; - priv->base.uevent->priv = priv; - nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nv04_fifo_intr; nv_engine(priv)->cclass = &nv84_fifo_cclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 4f226afb5591..b4365dde1859 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -150,8 +149,7 @@ nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend, nv_wr32(priv, 0x002634, chan->base.chid); if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) { - nv_error(priv, "channel %d [%s] kick timeout\n", - chan->base.chid, nouveau_client_name(chan)); + nv_error(priv, "channel %d kick timeout\n", chan->base.chid); if (suspend) return -EBUSY; } @@ -335,17 +333,17 @@ nvc0_fifo_cclass = { ******************************************************************************/ static const struct nouveau_enum nvc0_fifo_fault_unit[] = { - { 0x00, "PGRAPH", NULL, NVDEV_ENGINE_GR }, + { 0x00, "PGRAPH" }, { 0x03, "PEEPHOLE" }, { 0x04, "BAR1" }, { 0x05, "BAR3" }, - { 0x07, "PFIFO", NULL, NVDEV_ENGINE_FIFO }, - { 0x10, "PBSP", NULL, NVDEV_ENGINE_BSP }, - { 0x11, "PPPP", NULL, NVDEV_ENGINE_PPP }, + { 0x07, "PFIFO" }, + { 0x10, "PBSP" }, + { 0x11, "PPPP" }, { 0x13, "PCOUNTER" }, - { 0x14, "PVP", NULL, NVDEV_ENGINE_VP }, - { 0x15, "PCOPY0", NULL, NVDEV_ENGINE_COPY0 }, - { 0x16, "PCOPY1", NULL, NVDEV_ENGINE_COPY1 }, + { 0x14, "PVP" }, + { 0x15, "PCOPY0" }, + { 0x16, "PCOPY1" }, { 0x17, "PDAEMON" }, {} }; @@ -404,9 +402,6 @@ nvc0_fifo_isr_vm_fault(struct nvc0_fifo_priv *priv, int unit) u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10)); u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10)); u32 client = (stat & 0x00001f00) >> 8; - const struct nouveau_enum *en; - struct nouveau_engine *engine; - struct nouveau_object *engctx = NULL; switch (unit) { case 3: /* PEEPHOLE */ @@ -425,26 +420,16 @@ nvc0_fifo_isr_vm_fault(struct nvc0_fifo_priv *priv, int unit) nv_error(priv, "%s fault at 0x%010llx [", (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo); nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f); - pr_cont("] from "); - en = nouveau_enum_print(nvc0_fifo_fault_unit, unit); + printk("] from "); + nouveau_enum_print(nvc0_fifo_fault_unit, unit); if (stat & 0x00000040) { - pr_cont("/"); + printk("/"); nouveau_enum_print(nvc0_fifo_fault_hubclient, client); } else { - pr_cont("/GPC%d/", (stat & 0x1f000000) >> 24); + printk("/GPC%d/", (stat & 0x1f000000) >> 24); nouveau_enum_print(nvc0_fifo_fault_gpcclient, client); } - - if (en && en->data2) { - engine = nouveau_engine(priv, en->data2); - if (engine) - engctx = nouveau_engctx_get(engine, inst); - - } - pr_cont(" on channel 0x%010llx [%s]\n", (u64)inst << 12, - nouveau_client_name(engctx)); - - nouveau_engctx_put(engctx); + printk(" on channel 0x%010llx\n", (u64)inst << 12); } static int @@ -499,12 +484,10 @@ nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit) if (show) { nv_error(priv, "SUBFIFO%d:", unit); nouveau_bitfield_print(nvc0_fifo_subfifo_intr, show); - pr_cont("\n"); - nv_error(priv, - "SUBFIFO%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n", - unit, chid, - nouveau_client_name_for_fifo_chid(&priv->base, chid), - subc, mthd, data); + printk("\n"); + nv_error(priv, "SUBFIFO%d: ch %d subc %d mthd 0x%04x " + "data 0x%08x\n", + unit, chid, subc, mthd, data); } nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008); @@ -518,34 +501,12 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) u32 mask = nv_rd32(priv, 0x002140); u32 stat = nv_rd32(priv, 0x002100) & mask; - if (stat & 0x00000001) { - u32 intr = nv_rd32(priv, 0x00252c); - nv_warn(priv, "INTR 0x00000001: 0x%08x\n", intr); - nv_wr32(priv, 0x002100, 0x00000001); - stat &= ~0x00000001; - } - if (stat & 0x00000100) { - u32 intr = nv_rd32(priv, 0x00254c); - nv_warn(priv, "INTR 0x00000100: 0x%08x\n", intr); + nv_warn(priv, "unknown status 0x00000100\n"); nv_wr32(priv, 0x002100, 0x00000100); stat &= ~0x00000100; } - if (stat & 0x00010000) { - u32 intr = nv_rd32(priv, 0x00256c); - nv_warn(priv, "INTR 0x00010000: 0x%08x\n", intr); - nv_wr32(priv, 0x002100, 0x00010000); - stat &= ~0x00010000; - } - - if (stat & 0x01000000) { - u32 intr = nv_rd32(priv, 0x00258c); - nv_warn(priv, "INTR 0x01000000: 0x%08x\n", intr); - nv_wr32(priv, 0x002100, 0x01000000); - stat &= ~0x01000000; - } - if (stat & 0x10000000) { u32 units = nv_rd32(priv, 0x00259c); u32 u = units; @@ -575,20 +536,11 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) } if (stat & 0x40000000) { - u32 intr0 = nv_rd32(priv, 0x0025a4); - u32 intr1 = nv_mask(priv, 0x002a00, 0x00000000, 0x00000); - nv_debug(priv, "INTR 0x40000000: 0x%08x 0x%08x\n", - intr0, intr1); + nv_warn(priv, "unknown status 0x40000000\n"); + nv_mask(priv, 0x002a00, 0x00000000, 0x00000000); stat &= ~0x40000000; } - if (stat & 0x80000000) { - u32 intr = nv_mask(priv, 0x0025a8, 0x00000000, 0x00000000); - nouveau_event_trigger(priv->base.uevent, 0); - nv_debug(priv, "INTR 0x80000000: 0x%08x\n", intr); - stat &= ~0x80000000; - } - if (stat) { nv_fatal(priv, "unhandled status 0x%08x\n", stat); nv_wr32(priv, 0x002100, stat); @@ -596,20 +548,6 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) } } -static void -nvc0_fifo_uevent_enable(struct nouveau_event *event, int index) -{ - struct nvc0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x80000000); -} - -static void -nvc0_fifo_uevent_disable(struct nouveau_event *event, int index) -{ - struct nvc0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x00000000); -} - static int nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -643,10 +581,6 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nvc0_fifo_uevent_enable; - priv->base.uevent->disable = nvc0_fifo_uevent_disable; - priv->base.uevent->priv = priv; - nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nvc0_fifo_intr; nv_engine(priv)->cclass = &nvc0_fifo_cclass; @@ -705,8 +639,7 @@ nvc0_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */ nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0x3fffffff); - nv_wr32(priv, 0x002628, 0x00000001); /* makes mthd 0x20 work */ + nv_wr32(priv, 0x002140, 0xbfffffff); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 4419e40d88e9..c930da99c2c1 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -185,8 +184,7 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend, nv_wr32(priv, 0x002634, chan->base.chid); if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) { - nv_error(priv, "channel %d [%s] kick timeout\n", - chan->base.chid, nouveau_client_name(chan)); + nv_error(priv, "channel %d kick timeout\n", chan->base.chid); if (suspend) return -EBUSY; } @@ -414,34 +412,20 @@ nve0_fifo_isr_vm_fault(struct nve0_fifo_priv *priv, int unit) u32 vahi = nv_rd32(priv, 0x2808 + (unit * 0x10)); u32 stat = nv_rd32(priv, 0x280c + (unit * 0x10)); u32 client = (stat & 0x00001f00) >> 8; - const struct nouveau_enum *en; - struct nouveau_engine *engine; - struct nouveau_object *engctx = NULL; nv_error(priv, "PFIFO: %s fault at 0x%010llx [", (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo); nouveau_enum_print(nve0_fifo_fault_reason, stat & 0x0000000f); - pr_cont("] from "); - en = nouveau_enum_print(nve0_fifo_fault_unit, unit); + printk("] from "); + nouveau_enum_print(nve0_fifo_fault_unit, unit); if (stat & 0x00000040) { - pr_cont("/"); + printk("/"); nouveau_enum_print(nve0_fifo_fault_hubclient, client); } else { - pr_cont("/GPC%d/", (stat & 0x1f000000) >> 24); + printk("/GPC%d/", (stat & 0x1f000000) >> 24); nouveau_enum_print(nve0_fifo_fault_gpcclient, client); } - - if (en && en->data2) { - engine = nouveau_engine(priv, en->data2); - if (engine) - engctx = nouveau_engctx_get(engine, inst); - - } - - pr_cont(" on channel 0x%010llx [%s]\n", (u64)inst << 12, - nouveau_client_name(engctx)); - - nouveau_engctx_put(engctx); + printk(" on channel 0x%010llx\n", (u64)inst << 12); } static int @@ -496,12 +480,10 @@ nve0_fifo_isr_subfifo_intr(struct nve0_fifo_priv *priv, int unit) if (show) { nv_error(priv, "SUBFIFO%d:", unit); nouveau_bitfield_print(nve0_fifo_subfifo_intr, show); - pr_cont("\n"); - nv_error(priv, - "SUBFIFO%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n", - unit, chid, - nouveau_client_name_for_fifo_chid(&priv->base, chid), - subc, mthd, data); + printk("\n"); + nv_error(priv, "SUBFIFO%d: ch %d subc %d mthd 0x%04x " + "data 0x%08x\n", + unit, chid, subc, mthd, data); } nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008); @@ -555,12 +537,6 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) stat &= ~0x40000000; } - if (stat & 0x80000000) { - nouveau_event_trigger(priv->base.uevent, 0); - nv_wr32(priv, 0x002100, 0x80000000); - stat &= ~0x80000000; - } - if (stat) { nv_fatal(priv, "unhandled status 0x%08x\n", stat); nv_wr32(priv, 0x002100, stat); @@ -568,20 +544,6 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) } } -static void -nve0_fifo_uevent_enable(struct nouveau_event *event, int index) -{ - struct nve0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x80000000); -} - -static void -nve0_fifo_uevent_disable(struct nouveau_event *event, int index) -{ - struct nve0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x00000000); -} - static int nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -605,10 +567,6 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nve0_fifo_uevent_enable; - priv->base.uevent->disable = nve0_fifo_uevent_disable; - priv->base.uevent->priv = priv; - nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nve0_fifo_intr; nv_engine(priv)->cclass = &nve0_fifo_cclass; @@ -659,7 +617,7 @@ nve0_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x002a00, 0xffffffff); nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0x3fffffff); + nv_wr32(priv, 0x002140, 0xbfffffff); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c index ad13dcdd15f9..e30a9c5ff1fc 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c @@ -22,7 +22,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include #include #include #include @@ -1298,17 +1297,16 @@ nv04_graph_intr(struct nouveau_subdev *subdev) nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); if (show) { - nv_error(priv, "%s", ""); + nv_error(priv, ""); nouveau_bitfield_print(nv04_graph_intr_name, show); - pr_cont(" nsource:"); + printk(" nsource:"); nouveau_bitfield_print(nv04_graph_nsource, nsource); - pr_cont(" nstatus:"); + printk(" nstatus:"); nouveau_bitfield_print(nv04_graph_nstatus, nstatus); - pr_cont("\n"); - nv_error(priv, - "ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, nouveau_client_name(chan), subc, class, mthd, - data); + printk("\n"); + nv_error(priv, "ch %d/%d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); } nouveau_namedb_put(handle); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c index 23c143aaa556..5c0f843ea249 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c @@ -22,7 +22,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include #include #include #include @@ -1194,17 +1193,16 @@ nv10_graph_intr(struct nouveau_subdev *subdev) nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); if (show) { - nv_error(priv, "%s", ""); + nv_error(priv, ""); nouveau_bitfield_print(nv10_graph_intr_name, show); - pr_cont(" nsource:"); + printk(" nsource:"); nouveau_bitfield_print(nv04_graph_nsource, nsource); - pr_cont(" nstatus:"); + printk(" nstatus:"); nouveau_bitfield_print(nv10_graph_nstatus, nstatus); - pr_cont("\n"); - nv_error(priv, - "ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, nouveau_client_name(chan), subc, class, mthd, - data); + printk("\n"); + nv_error(priv, "ch %d/%d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); } nouveau_namedb_put(handle); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c index 0607b9801748..5b20401bf911 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -225,17 +224,15 @@ nv20_graph_intr(struct nouveau_subdev *subdev) nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); if (show) { - nv_error(priv, "%s", ""); + nv_error(priv, ""); nouveau_bitfield_print(nv10_graph_intr_name, show); - pr_cont(" nsource:"); + printk(" nsource:"); nouveau_bitfield_print(nv04_graph_nsource, nsource); - pr_cont(" nstatus:"); + printk(" nstatus:"); nouveau_bitfield_print(nv10_graph_nstatus, nstatus); - pr_cont("\n"); - nv_error(priv, - "ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, nouveau_client_name(engctx), subc, class, mthd, - data); + printk("\n"); + nv_error(priv, "ch %d/%d class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); } nouveau_engctx_put(engctx); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 17049d5c723d..0b36dd3deebd 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -22,7 +22,6 @@ * Authors: Ben Skeggs */ -#include #include #include #include @@ -322,17 +321,16 @@ nv40_graph_intr(struct nouveau_subdev *subdev) nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); if (show) { - nv_error(priv, "%s", ""); + nv_error(priv, ""); nouveau_bitfield_print(nv10_graph_intr_name, show); - pr_cont(" nsource:"); + printk(" nsource:"); nouveau_bitfield_print(nv04_graph_nsource, nsource); - pr_cont(" nstatus:"); + printk(" nstatus:"); nouveau_bitfield_print(nv10_graph_nstatus, nstatus); - pr_cont("\n"); - nv_error(priv, - "ch %d [0x%08x %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst << 4, nouveau_client_name(engctx), subc, - class, mthd, data); + printk("\n"); + nv_error(priv, "ch %d [0x%08x] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, inst << 4, subc, class, mthd, data); } nouveau_engctx_put(engctx); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index f2b1a7a124f2..b1c3d835b4c2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -419,7 +418,7 @@ nv50_priv_mp_trap(struct nv50_graph_priv *priv, int tpid, int display) nv_error(priv, "TRAP_MP_EXEC - " "TP %d MP %d: ", tpid, i); nouveau_enum_print(nv50_mp_exec_error_names, status); - pr_cont(" at %06x warp %d, opcode %08x %08x\n", + printk(" at %06x warp %d, opcode %08x %08x\n", pc&0xffffff, pc >> 24, oplow, ophigh); } @@ -533,7 +532,7 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old, static int nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, - int chid, u64 inst, struct nouveau_object *engctx) + int chid, u64 inst) { u32 status = nv_rd32(priv, 0x400108); u32 ustatus; @@ -566,11 +565,12 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, nv_error(priv, "TRAP DISPATCH_FAULT\n"); if (display && (addr & 0x80000000)) { - nv_error(priv, - "ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x%08x 400808 0x%08x 400848 0x%08x\n", - chid, inst, - nouveau_client_name(engctx), subc, - class, mthd, datah, datal, addr, r848); + nv_error(priv, "ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x%08x " + "400808 0x%08x 400848 0x%08x\n", + chid, inst, subc, class, mthd, datah, + datal, addr, r848); } else if (display) { nv_error(priv, "no stuck command?\n"); @@ -591,11 +591,11 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, nv_error(priv, "TRAP DISPATCH_QUERY\n"); if (display && (addr & 0x80000000)) { - nv_error(priv, - "ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x 40084c 0x%08x\n", - chid, inst, - nouveau_client_name(engctx), subc, - class, mthd, data, addr); + nv_error(priv, "ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x 40084c 0x%08x\n", + chid, inst, subc, class, mthd, + data, addr); } else if (display) { nv_error(priv, "no stuck command?\n"); @@ -623,7 +623,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, if (display) { nv_error(priv, "TRAP_M2MF"); nouveau_bitfield_print(nv50_graph_trap_m2mf, ustatus); - pr_cont("\n"); + printk("\n"); nv_error(priv, "TRAP_M2MF %08x %08x %08x %08x\n", nv_rd32(priv, 0x406804), nv_rd32(priv, 0x406808), nv_rd32(priv, 0x40680c), nv_rd32(priv, 0x406810)); @@ -644,7 +644,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, if (display) { nv_error(priv, "TRAP_VFETCH"); nouveau_bitfield_print(nv50_graph_trap_vfetch, ustatus); - pr_cont("\n"); + printk("\n"); nv_error(priv, "TRAP_VFETCH %08x %08x %08x %08x\n", nv_rd32(priv, 0x400c00), nv_rd32(priv, 0x400c08), nv_rd32(priv, 0x400c0c), nv_rd32(priv, 0x400c10)); @@ -661,7 +661,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, if (display) { nv_error(priv, "TRAP_STRMOUT"); nouveau_bitfield_print(nv50_graph_trap_strmout, ustatus); - pr_cont("\n"); + printk("\n"); nv_error(priv, "TRAP_STRMOUT %08x %08x %08x %08x\n", nv_rd32(priv, 0x401804), nv_rd32(priv, 0x401808), nv_rd32(priv, 0x40180c), nv_rd32(priv, 0x401810)); @@ -682,7 +682,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, if (display) { nv_error(priv, "TRAP_CCACHE"); nouveau_bitfield_print(nv50_graph_trap_ccache, ustatus); - pr_cont("\n"); + printk("\n"); nv_error(priv, "TRAP_CCACHE %08x %08x %08x %08x" " %08x %08x %08x\n", nv_rd32(priv, 0x405000), nv_rd32(priv, 0x405004), @@ -774,12 +774,11 @@ nv50_graph_intr(struct nouveau_subdev *subdev) u32 ecode = nv_rd32(priv, 0x400110); nv_error(priv, "DATA_ERROR "); nouveau_enum_print(nv50_data_error_names, ecode); - pr_cont("\n"); + printk("\n"); } if (stat & 0x00200000) { - if (!nv50_graph_trap_handler(priv, show, chid, (u64)inst << 12, - engctx)) + if (!nv50_graph_trap_handler(priv, show, chid, (u64)inst << 12)) show &= ~0x00200000; } @@ -787,13 +786,12 @@ nv50_graph_intr(struct nouveau_subdev *subdev) nv_wr32(priv, 0x400500, 0x00010001); if (show) { - nv_error(priv, "%s", ""); + nv_error(priv, ""); nouveau_bitfield_print(nv50_graph_intr_name, show); - pr_cont("\n"); - nv_error(priv, - "ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, (u64)inst << 12, nouveau_client_name(engctx), - subc, class, mthd, data); + printk("\n"); + nv_error(priv, "ch %d [0x%010llx] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, (u64)inst << 12, subc, class, mthd, data); } if (nv_rd32(priv, 0x400824) & (1 << 31)) @@ -909,8 +907,9 @@ nv50_graph_init(struct nouveau_object *object) nv_wr32(priv, 0x400828, 0x00000000); nv_wr32(priv, 0x40082c, 0x00000000); nv_wr32(priv, 0x400830, 0x00000000); + nv_wr32(priv, 0x400724, 0x00000000); nv_wr32(priv, 0x40032c, 0x00000000); - nv_wr32(priv, 0x400330, 0x00000000); + nv_wr32(priv, 0x400320, 4); /* CTXCTL_CMD = NEWCTXDMA */ /* some unknown zcull magic */ switch (nv_device(priv)->chipset & 0xf0) { diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index 0de0dd724aff..45aff5f5085a 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -433,10 +433,10 @@ nvc0_graph_intr(struct nouveau_subdev *subdev) if (stat & 0x00000010) { handle = nouveau_handle_get_class(engctx, class); if (!handle || nv_call(handle->object, mthd, data)) { - nv_error(priv, - "ILLEGAL_MTHD ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst << 12, nouveau_client_name(engctx), - subc, class, mthd, data); + nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x\n", + chid, inst << 12, subc, class, mthd, data); } nouveau_handle_put(handle); nv_wr32(priv, 0x400100, 0x00000010); @@ -444,10 +444,9 @@ nvc0_graph_intr(struct nouveau_subdev *subdev) } if (stat & 0x00000020) { - nv_error(priv, - "ILLEGAL_CLASS ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst << 12, nouveau_client_name(engctx), subc, - class, mthd, data); + nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d " + "class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, inst << 12, subc, class, mthd, data); nv_wr32(priv, 0x400100, 0x00000020); stat &= ~0x00000020; } @@ -455,16 +454,15 @@ nvc0_graph_intr(struct nouveau_subdev *subdev) if (stat & 0x00100000) { nv_error(priv, "DATA_ERROR ["); nouveau_enum_print(nv50_data_error_names, code); - pr_cont("] ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst << 12, nouveau_client_name(engctx), subc, - class, mthd, data); + printk("] ch %d [0x%010llx] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, inst << 12, subc, class, mthd, data); nv_wr32(priv, 0x400100, 0x00100000); stat &= ~0x00100000; } if (stat & 0x00200000) { - nv_error(priv, "TRAP ch %d [0x%010llx %s]\n", chid, inst << 12, - nouveau_client_name(engctx)); + nv_error(priv, "TRAP ch %d [0x%010llx]\n", chid, inst << 12); nvc0_graph_trap_intr(priv); nv_wr32(priv, 0x400100, 0x00200000); stat &= ~0x00200000; @@ -613,8 +611,10 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, static void nvc0_graph_dtor_fw(struct nvc0_graph_fuc *fuc) { - kfree(fuc->data); - fuc->data = NULL; + if (fuc->data) { + kfree(fuc->data); + fuc->data = NULL; + } } void @@ -622,7 +622,8 @@ nvc0_graph_dtor(struct nouveau_object *object) { struct nvc0_graph_priv *priv = (void *)object; - kfree(priv->data); + if (priv->data) + kfree(priv->data); nvc0_graph_dtor_fw(&priv->fuc409c); nvc0_graph_dtor_fw(&priv->fuc409d); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c index 61cec0f6ff1c..9f82e9702b46 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c @@ -78,16 +78,15 @@ nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) } static void -nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst, - struct nouveau_object *engctx) +nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst) { u32 trap = nv_rd32(priv, 0x400108); int rop; if (trap & 0x00000001) { u32 stat = nv_rd32(priv, 0x404000); - nv_error(priv, "DISPATCH ch %d [0x%010llx %s] 0x%08x\n", - chid, inst, nouveau_client_name(engctx), stat); + nv_error(priv, "DISPATCH ch %d [0x%010llx] 0x%08x\n", + chid, inst, stat); nv_wr32(priv, 0x404000, 0xc0000000); nv_wr32(priv, 0x400108, 0x00000001); trap &= ~0x00000001; @@ -95,8 +94,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst, if (trap & 0x00000010) { u32 stat = nv_rd32(priv, 0x405840); - nv_error(priv, "SHADER ch %d [0x%010llx %s] 0x%08x\n", - chid, inst, nouveau_client_name(engctx), stat); + nv_error(priv, "SHADER ch %d [0x%010llx] 0x%08x\n", + chid, inst, stat); nv_wr32(priv, 0x405840, 0xc0000000); nv_wr32(priv, 0x400108, 0x00000010); trap &= ~0x00000010; @@ -106,10 +105,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst, for (rop = 0; rop < priv->rop_nr; rop++) { u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070)); u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144)); - nv_error(priv, - "ROP%d ch %d [0x%010llx %s] 0x%08x 0x%08x\n", - rop, chid, inst, nouveau_client_name(engctx), - statz, statc); + nv_error(priv, "ROP%d ch %d [0x%010llx] 0x%08x 0x%08x\n", + rop, chid, inst, statz, statc); nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); } @@ -118,8 +115,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst, } if (trap) { - nv_error(priv, "TRAP ch %d [0x%010llx %s] 0x%08x\n", - chid, inst, nouveau_client_name(engctx), trap); + nv_error(priv, "TRAP ch %d [0x%010llx] 0x%08x\n", + chid, inst, trap); nv_wr32(priv, 0x400108, trap); } } @@ -148,10 +145,10 @@ nve0_graph_intr(struct nouveau_subdev *subdev) if (stat & 0x00000010) { handle = nouveau_handle_get_class(engctx, class); if (!handle || nv_call(handle->object, mthd, data)) { - nv_error(priv, - "ILLEGAL_MTHD ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, nouveau_client_name(engctx), subc, - class, mthd, data); + nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x\n", + chid, inst, subc, class, mthd, data); } nouveau_handle_put(handle); nv_wr32(priv, 0x400100, 0x00000010); @@ -159,10 +156,9 @@ nve0_graph_intr(struct nouveau_subdev *subdev) } if (stat & 0x00000020) { - nv_error(priv, - "ILLEGAL_CLASS ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, nouveau_client_name(engctx), subc, class, - mthd, data); + nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d " + "class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); nv_wr32(priv, 0x400100, 0x00000020); stat &= ~0x00000020; } @@ -170,15 +166,15 @@ nve0_graph_intr(struct nouveau_subdev *subdev) if (stat & 0x00100000) { nv_error(priv, "DATA_ERROR ["); nouveau_enum_print(nv50_data_error_names, code); - pr_cont("] ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, nouveau_client_name(engctx), subc, class, - mthd, data); + printk("] ch %d [0x%010llx] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); nv_wr32(priv, 0x400100, 0x00100000); stat &= ~0x00100000; } if (stat & 0x00200000) { - nve0_graph_trap_isr(priv, chid, inst, engctx); + nve0_graph_trap_isr(priv, chid, inst); nv_wr32(priv, 0x400100, 0x00200000); stat &= ~0x00200000; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c index 49ecbb859b25..9fd86375f4c4 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c @@ -22,7 +22,6 @@ * Authors: Ben Skeggs */ -#include #include #include #include @@ -232,10 +231,8 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev) 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); + nv_error(priv, "ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n", + chid, inst << 4, stat, type, mthd, data); } nouveau_engctx_put(engctx); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/software/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/software/nv50.c index c48e74953771..b0e7e1c01ce6 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/software/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/software/nv50.c @@ -28,9 +28,6 @@ #include #include #include -#include - -#include #include #include @@ -93,11 +90,18 @@ nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd, { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); struct nouveau_disp *disp = nouveau_disp(object); + unsigned long flags; u32 crtc = *(u32 *)args; + if (crtc > 1) return -EINVAL; - nouveau_event_get(disp->vblank, crtc, &chan->base.vblank.event); + disp->vblank.get(disp->vblank.data, crtc); + + spin_lock_irqsave(&disp->vblank.lock, flags); + list_add(&chan->base.vblank.head, &disp->vblank.list); + chan->base.vblank.crtc = crtc; + spin_unlock_irqrestore(&disp->vblank.lock, flags); return 0; } @@ -131,29 +135,6 @@ nv50_software_sclass[] = { * software context ******************************************************************************/ -static int -nv50_software_vblsem_release(struct nouveau_eventh *event, int head) -{ - 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); - - nv_wr32(priv, 0x001704, chan->vblank.channel); - nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); - bar->flush(bar); - - if (nv_device(priv)->chipset == 0x50) { - nv_wr32(priv, 0x001570, chan->vblank.offset); - nv_wr32(priv, 0x001574, chan->vblank.value); - } else { - nv_wr32(priv, 0x060010, chan->vblank.offset); - nv_wr32(priv, 0x060014, chan->vblank.value); - } - - return NVKM_EVENT_DROP; -} - static int nv50_software_context_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -169,7 +150,6 @@ nv50_software_context_ctor(struct nouveau_object *parent, return ret; chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12; - chan->base.vblank.event.func = nv50_software_vblsem_release; return 0; } @@ -190,8 +170,8 @@ nv50_software_cclass = { 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 nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { struct nv50_software_priv *priv; int ret; diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c index a523eaad47e3..282a1cd1bc2f 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c @@ -25,9 +25,6 @@ #include #include #include -#include - -#include #include #include @@ -75,12 +72,18 @@ nvc0_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd, { struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); struct nouveau_disp *disp = nouveau_disp(object); + unsigned long flags; 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); + disp->vblank.get(disp->vblank.data, crtc); + + spin_lock_irqsave(&disp->vblank.lock, flags); + list_add(&chan->base.vblank.head, &disp->vblank.list); + chan->base.vblank.crtc = crtc; + spin_unlock_irqrestore(&disp->vblank.lock, flags); return 0; } @@ -114,23 +117,6 @@ nvc0_software_sclass[] = { * software context ******************************************************************************/ -static int -nvc0_software_vblsem_release(struct nouveau_eventh *event, int head) -{ - 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); - bar->flush(bar); - nv_wr32(priv, 0x06000c, upper_32_bits(chan->vblank.offset)); - nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset)); - nv_wr32(priv, 0x060014, chan->vblank.value); - - return NVKM_EVENT_DROP; -} - static int nvc0_software_context_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -146,7 +132,6 @@ nvc0_software_context_ctor(struct nouveau_object *parent, return ret; chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12; - chan->base.vblank.event.func = nvc0_software_vblsem_release; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/class.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/class.h index 92d3ab11d962..47c4b3a5bd3a 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -154,14 +154,6 @@ struct nve0_channel_ind_class { u32 engine; }; -/* 0046: NV04_DISP - */ - -#define NV04_DISP_CLASS 0x00000046 - -struct nv04_display_class { -}; - /* 5070: NV50_DISP * 8270: NV84_DISP * 8370: NVA0_DISP @@ -198,6 +190,25 @@ struct nv04_display_class { #define NV84_DISP_SOR_HDMI_PWR_REKEY 0x0000007f #define NV50_DISP_SOR_LVDS_SCRIPT 0x00013000 #define NV50_DISP_SOR_LVDS_SCRIPT_ID 0x0000ffff +#define NV94_DISP_SOR_DP_TRAIN 0x00016000 +#define NV94_DISP_SOR_DP_TRAIN_OP 0xf0000000 +#define NV94_DISP_SOR_DP_TRAIN_OP_PATTERN 0x00000000 +#define NV94_DISP_SOR_DP_TRAIN_OP_INIT 0x10000000 +#define NV94_DISP_SOR_DP_TRAIN_OP_FINI 0x20000000 +#define NV94_DISP_SOR_DP_TRAIN_INIT_SPREAD 0x00000001 +#define NV94_DISP_SOR_DP_TRAIN_INIT_SPREAD_OFF 0x00000000 +#define NV94_DISP_SOR_DP_TRAIN_INIT_SPREAD_ON 0x00000001 +#define NV94_DISP_SOR_DP_TRAIN_PATTERN 0x00000003 +#define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED 0x00000000 +#define NV94_DISP_SOR_DP_LNKCTL 0x00016040 +#define NV94_DISP_SOR_DP_LNKCTL_FRAME 0x80000000 +#define NV94_DISP_SOR_DP_LNKCTL_FRAME_STD 0x00000000 +#define NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH 0x80000000 +#define NV94_DISP_SOR_DP_LNKCTL_WIDTH 0x00001f00 +#define NV94_DISP_SOR_DP_LNKCTL_COUNT 0x00000007 +#define NV94_DISP_SOR_DP_DRVCTL(l) ((l) * 0x40 + 0x00016100) +#define NV94_DISP_SOR_DP_DRVCTL_VS 0x00000300 +#define NV94_DISP_SOR_DP_DRVCTL_PE 0x00000003 #define NV50_DISP_DAC_MTHD 0x00020000 #define NV50_DISP_DAC_MTHD_TYPE 0x0000f000 @@ -219,23 +230,6 @@ struct nv04_display_class { #define NV50_DISP_DAC_LOAD 0x0002000c #define NV50_DISP_DAC_LOAD_VALUE 0x00000007 -#define NV50_DISP_PIOR_MTHD 0x00030000 -#define NV50_DISP_PIOR_MTHD_TYPE 0x0000f000 -#define NV50_DISP_PIOR_MTHD_OR 0x00000003 - -#define NV50_DISP_PIOR_PWR 0x00030000 -#define NV50_DISP_PIOR_PWR_STATE 0x00000001 -#define NV50_DISP_PIOR_PWR_STATE_ON 0x00000001 -#define NV50_DISP_PIOR_PWR_STATE_OFF 0x00000000 -#define NV50_DISP_PIOR_TMDS_PWR 0x00032000 -#define NV50_DISP_PIOR_TMDS_PWR_STATE 0x00000001 -#define NV50_DISP_PIOR_TMDS_PWR_STATE_ON 0x00000001 -#define NV50_DISP_PIOR_TMDS_PWR_STATE_OFF 0x00000000 -#define NV50_DISP_PIOR_DP_PWR 0x00036000 -#define NV50_DISP_PIOR_DP_PWR_STATE 0x00000001 -#define NV50_DISP_PIOR_DP_PWR_STATE_ON 0x00000001 -#define NV50_DISP_PIOR_DP_PWR_STATE_OFF 0x00000000 - struct nv50_display_class { }; diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h index c66eac513803..63acc0346ff2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/client.h @@ -7,7 +7,7 @@ struct nouveau_client { struct nouveau_namedb base; struct nouveau_handle *root; struct nouveau_object *device; - char name[32]; + char name[16]; u32 debug; struct nouveau_vm *vm; }; @@ -41,6 +41,5 @@ int nouveau_client_create_(const char *name, u64 device, const char *cfg, int nouveau_client_init(struct nouveau_client *); int nouveau_client_fini(struct nouveau_client *, bool suspend); -const char *nouveau_client_name(void *obj); #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/device.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/device.h index d351a4e5819c..e58b6f0984c1 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/device.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/device.h @@ -26,7 +26,6 @@ enum nv_subdev_type { */ NVDEV_SUBDEV_MXM, NVDEV_SUBDEV_MC, - NVDEV_SUBDEV_BUS, NVDEV_SUBDEV_TIMER, NVDEV_SUBDEV_FB, NVDEV_SUBDEV_LTCG, diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/enum.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/enum.h index 4fc62bb8c1f0..e7b1e181943b 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/enum.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/enum.h @@ -5,13 +5,12 @@ struct nouveau_enum { u32 value; const char *name; const void *data; - u32 data2; }; const struct nouveau_enum * nouveau_enum_find(const struct nouveau_enum *, u32 value); -const struct nouveau_enum * +void nouveau_enum_print(const struct nouveau_enum *en, u32 value); struct nouveau_bitfield { diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/event.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/event.h deleted file mode 100644 index 9e094408f14e..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/event.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __NVKM_EVENT_H__ -#define __NVKM_EVENT_H__ - -/* return codes from event handlers */ -#define NVKM_EVENT_DROP 0 -#define NVKM_EVENT_KEEP 1 - -struct nouveau_eventh { - struct list_head head; - int (*func)(struct nouveau_eventh *, int index); -}; - -struct nouveau_event { - spinlock_t lock; - - void *priv; - void (*enable)(struct nouveau_event *, int index); - void (*disable)(struct nouveau_event *, int index); - - int index_nr; - struct { - struct list_head list; - int refs; - } index[]; -}; - -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); - -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/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h index 6a902672f6f4..5982935ee23a 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h @@ -133,7 +133,7 @@ static inline u8 nv_ro08(void *obj, u64 addr) { u8 data = nv_ofuncs(obj)->rd08(obj, addr); - nv_spam(obj, "nv_ro08 0x%08llx 0x%02x\n", addr, data); + nv_spam(obj, "nv_ro08 0x%08x 0x%02x\n", addr, data); return data; } @@ -141,7 +141,7 @@ static inline u16 nv_ro16(void *obj, u64 addr) { u16 data = nv_ofuncs(obj)->rd16(obj, addr); - nv_spam(obj, "nv_ro16 0x%08llx 0x%04x\n", addr, data); + nv_spam(obj, "nv_ro16 0x%08x 0x%04x\n", addr, data); return data; } @@ -149,28 +149,28 @@ static inline u32 nv_ro32(void *obj, u64 addr) { u32 data = nv_ofuncs(obj)->rd32(obj, addr); - nv_spam(obj, "nv_ro32 0x%08llx 0x%08x\n", addr, data); + nv_spam(obj, "nv_ro32 0x%08x 0x%08x\n", addr, data); return data; } static inline void nv_wo08(void *obj, u64 addr, u8 data) { - nv_spam(obj, "nv_wo08 0x%08llx 0x%02x\n", addr, data); + nv_spam(obj, "nv_wo08 0x%08x 0x%02x\n", addr, data); nv_ofuncs(obj)->wr08(obj, addr, data); } static inline void nv_wo16(void *obj, u64 addr, u16 data) { - nv_spam(obj, "nv_wo16 0x%08llx 0x%04x\n", addr, data); + nv_spam(obj, "nv_wo16 0x%08x 0x%04x\n", addr, data); nv_ofuncs(obj)->wr16(obj, addr, data); } static inline void nv_wo32(void *obj, u64 addr, u32 data) { - nv_spam(obj, "nv_wo32 0x%08llx 0x%08x\n", addr, data); + nv_spam(obj, "nv_wo32 0x%08x 0x%08x\n", addr, data); nv_ofuncs(obj)->wr32(obj, addr, data); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/printk.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/printk.h index febed2ea5c80..1d629664f32d 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/printk.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/printk.h @@ -15,8 +15,7 @@ struct nouveau_object; #define NV_PRINTK_TRACE KERN_DEBUG #define NV_PRINTK_SPAM KERN_DEBUG -void __printf(4, 5) -nv_printk_(struct nouveau_object *, const char *, int, const char *, ...); +void 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) \ diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/engine/disp.h b/trunk/drivers/gpu/drm/nouveau/core/include/engine/disp.h index 28da6772c095..46948285f3e7 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/engine/disp.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/engine/disp.h @@ -4,11 +4,18 @@ #include #include #include -#include struct nouveau_disp { struct nouveau_engine base; - struct nouveau_event *vblank; + + struct { + struct list_head list; + spinlock_t lock; + void (*notify)(void *, int); + void (*get)(void *, int); + void (*put)(void *, int); + void *data; + } vblank; }; static inline struct nouveau_disp * @@ -17,22 +24,16 @@ nouveau_disp(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_DISP]; } -#define nouveau_disp_create(p,e,c,h,i,x,d) \ - nouveau_disp_create_((p), (e), (c), (h), (i), (x), \ - sizeof(**d), (void **)d) -#define nouveau_disp_destroy(d) ({ \ - struct nouveau_disp *disp = (d); \ - _nouveau_disp_dtor(nv_object(disp)); \ -}) +#define nouveau_disp_create(p,e,c,i,x,d) \ + nouveau_engine_create((p), (e), (c), true, (i), (x), (d)) +#define nouveau_disp_destroy(d) \ + nouveau_engine_destroy(&(d)->base) #define nouveau_disp_init(d) \ nouveau_engine_init(&(d)->base) #define nouveau_disp_fini(d,s) \ nouveau_engine_fini(&(d)->base, (s)) -int nouveau_disp_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int heads, - const char *, const char *, int, void **); -void _nouveau_disp_dtor(struct nouveau_object *); +#define _nouveau_disp_dtor _nouveau_engine_dtor #define _nouveau_disp_init _nouveau_engine_init #define _nouveau_disp_fini _nouveau_engine_fini diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/trunk/drivers/gpu/drm/nouveau/core/include/engine/fifo.h index b46c197709f3..f18846c8c6fe 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/engine/fifo.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/engine/fifo.h @@ -65,8 +65,6 @@ struct nouveau_fifo_base { struct nouveau_fifo { struct nouveau_engine base; - struct nouveau_event *uevent; - struct nouveau_object **channel; spinlock_t lock; u16 min; @@ -94,8 +92,6 @@ int nouveau_fifo_create_(struct nouveau_object *, struct nouveau_object *, struct nouveau_oclass *, int min, int max, int size, void **); void nouveau_fifo_destroy(struct nouveau_fifo *); -const char * -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 diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/engine/software.h b/trunk/drivers/gpu/drm/nouveau/core/include/engine/software.h index 45799487e573..c945691c8564 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/engine/software.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/engine/software.h @@ -3,17 +3,17 @@ #include #include -#include struct nouveau_software_chan { struct nouveau_engctx base; struct { - struct nouveau_eventh event; + struct list_head head; u32 channel; u32 ctxdma; u64 offset; u32 value; + u32 crtc; } vblank; int (*flip)(void *); diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h index 123270e9813a..b79025da581e 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h @@ -16,8 +16,6 @@ enum dcb_output_type { struct dcb_output { int index; /* may not be raw dcb index if merging has happened */ - u16 hasht; - u16 hashm; enum dcb_output_type type; uint8_t i2c_index; uint8_t heads; @@ -27,7 +25,6 @@ struct dcb_output { uint8_t or; uint8_t link; bool duallink_possible; - uint8_t extdev; union { struct sor_conf { int link; diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h index 96d3364f6db3..e6563b5cb08e 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h @@ -1,22 +1,17 @@ #ifndef __NVBIOS_GPIO_H__ #define __NVBIOS_GPIO_H__ +struct nouveau_bios; + enum dcb_gpio_func_name { DCB_GPIO_PANEL_POWER = 0x01, DCB_GPIO_TVDAC0 = 0x0c, DCB_GPIO_TVDAC1 = 0x2d, - DCB_GPIO_FAN = 0x09, + DCB_GPIO_PWM_FAN = 0x09, DCB_GPIO_FAN_SENSE = 0x3d, DCB_GPIO_UNUSED = 0xff }; -#define DCB_GPIO_LOG_DIR 0x02 -#define DCB_GPIO_LOG_DIR_OUT 0x00 -#define DCB_GPIO_LOG_DIR_IN 0x02 -#define DCB_GPIO_LOG_VAL 0x01 -#define DCB_GPIO_LOG_VAL_LO 0x00 -#define DCB_GPIO_LOG_VAL_HI 0x01 - struct dcb_gpio_func { u8 func; u8 line; diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h index 10b57a19a7de..5079bedfd985 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h @@ -15,7 +15,7 @@ struct dcb_i2c_entry { enum dcb_i2c_type type; u8 drive; u8 sense; - u8 share; + u32 data; }; u16 dcb_i2c_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h index 083541dbe9c8..a2c4296fc5f6 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h @@ -23,27 +23,11 @@ struct nvbios_therm_sensor { struct nvbios_therm_threshold thrs_shutdown; }; -/* no vbios have more than 6 */ -#define NOUVEAU_TEMP_FAN_TRIP_MAX 10 -struct nouveau_therm_trip_point { - int fan_duty; - int temp; - int hysteresis; -}; - struct nvbios_therm_fan { u16 pwm_freq; u8 min_duty; u8 max_duty; - - u16 bump_period; - u16 slow_down_period; - - struct nouveau_therm_trip_point trip[NOUVEAU_TEMP_FAN_TRIP_MAX]; - u8 nr_fan_trip; - u8 linear_min_temp; - u8 linear_max_temp; }; enum nvbios_therm_domain { diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h deleted file mode 100644 index 360baab52e4c..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __NVBIOS_XPIO_H__ -#define __NVBIOS_XPIO_H__ - -#define NVBIOS_XPIO_FLAG_AUX 0x10 -#define NVBIOS_XPIO_FLAG_AUX0 0x00 -#define NVBIOS_XPIO_FLAG_AUX1 0x10 - -struct nvbios_xpio { - u8 type; - u8 addr; - u8 flags; -}; - -u16 dcb_xpio_table(struct nouveau_bios *, u8 idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len); -u16 dcb_xpio_parse(struct nouveau_bios *, u8 idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_xpio *); - -#endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bus.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bus.h deleted file mode 100644 index 7d88ec4a6d06..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/bus.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __NOUVEAU_BUS_H__ -#define __NOUVEAU_BUS_H__ - -#include -#include - -struct nouveau_bus_intr { - u32 stat; - u32 unit; -}; - -struct nouveau_bus { - struct nouveau_subdev base; -}; - -static inline struct nouveau_bus * -nouveau_bus(void *obj) -{ - return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_BUS]; -} - -#define nouveau_bus_create(p, e, o, d) \ - nouveau_subdev_create_((p), (e), (o), 0, "PBUS", "master", \ - sizeof(**d), (void **)d) -#define nouveau_bus_destroy(p) \ - nouveau_subdev_destroy(&(p)->base) -#define nouveau_bus_init(p) \ - nouveau_subdev_init(&(p)->base) -#define nouveau_bus_fini(p, s) \ - nouveau_subdev_fini(&(p)->base, (s)) - -#define _nouveau_bus_dtor _nouveau_subdev_dtor -#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 nvc0_bus_oclass; - -#endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h index c85b9f1579ad..b75e8f18e52c 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -11,18 +10,28 @@ struct nouveau_gpio { struct nouveau_subdev base; - struct nouveau_event *events; - /* hardware interfaces */ void (*reset)(struct nouveau_gpio *, u8 func); int (*drive)(struct nouveau_gpio *, int line, int dir, int out); int (*sense)(struct nouveau_gpio *, int line); + void (*irq_enable)(struct nouveau_gpio *, int line, bool); /* software interfaces */ int (*find)(struct nouveau_gpio *, int idx, u8 tag, u8 line, struct dcb_gpio_func *); int (*set)(struct nouveau_gpio *, int idx, u8 tag, u8 line, int state); int (*get)(struct nouveau_gpio *, int idx, u8 tag, u8 line); + int (*irq)(struct nouveau_gpio *, int idx, u8 tag, u8 line, bool on); + + /* interrupt handling */ + struct list_head isr; + spinlock_t lock; + + void (*isr_run)(struct nouveau_gpio *, int idx, u32 mask); + int (*isr_add)(struct nouveau_gpio *, int idx, u8 tag, u8 line, + void (*)(void *, int state), void *data); + void (*isr_del)(struct nouveau_gpio *, int idx, u8 tag, u8 line, + void (*)(void *, int state), void *data); }; static inline struct nouveau_gpio * @@ -31,23 +40,25 @@ nouveau_gpio(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_GPIO]; } -#define nouveau_gpio_create(p,e,o,l,d) \ - nouveau_gpio_create_((p), (e), (o), (l), sizeof(**d), (void **)d) -#define nouveau_gpio_destroy(p) ({ \ - struct nouveau_gpio *gpio = (p); \ - _nouveau_gpio_dtor(nv_object(gpio)); \ -}) +#define nouveau_gpio_create(p,e,o,d) \ + nouveau_gpio_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_gpio_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) #define nouveau_gpio_fini(p,s) \ nouveau_subdev_fini(&(p)->base, (s)) -int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, int, void **); -void _nouveau_gpio_dtor(struct nouveau_object *); -int nouveau_gpio_init(struct nouveau_gpio *); +int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +int nouveau_gpio_init(struct nouveau_gpio *); extern struct nouveau_oclass nv10_gpio_oclass; extern struct nouveau_oclass nv50_gpio_oclass; extern struct nouveau_oclass nvd0_gpio_oclass; -extern struct nouveau_oclass nve0_gpio_oclass; + +void nv50_gpio_dtor(struct nouveau_object *); +int nv50_gpio_init(struct nouveau_object *); +int nv50_gpio_fini(struct nouveau_object *, bool); +void nv50_gpio_intr(struct nouveau_subdev *); +void nv50_gpio_irq_enable(struct nouveau_gpio *, int line, bool); #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h index 888384c0bed8..b93ab01e3785 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h @@ -10,59 +10,23 @@ #define NV_I2C_PORT(n) (0x00 + (n)) #define NV_I2C_DEFAULT(n) (0x80 + (n)) -#define NV_I2C_TYPE_DCBI2C(n) (0x0000 | (n)) -#define NV_I2C_TYPE_EXTDDC(e) (0x0005 | (e) << 8) -#define NV_I2C_TYPE_EXTAUX(e) (0x0006 | (e) << 8) - struct nouveau_i2c_port { - struct nouveau_object base; struct i2c_adapter adapter; - + struct nouveau_i2c *i2c; + struct i2c_algo_bit_data bit; struct list_head head; u8 index; - - const struct nouveau_i2c_func *func; -}; - -struct nouveau_i2c_func { - void (*acquire)(struct nouveau_i2c_port *); - void (*release)(struct nouveau_i2c_port *); - - void (*drive_scl)(struct nouveau_i2c_port *, int); - void (*drive_sda)(struct nouveau_i2c_port *, int); - int (*sense_scl)(struct nouveau_i2c_port *); - int (*sense_sda)(struct nouveau_i2c_port *); - - int (*aux)(struct nouveau_i2c_port *, u8, u32, u8 *, u8); - int (*pattern)(struct nouveau_i2c_port *, int pattern); - int (*lnk_ctl)(struct nouveau_i2c_port *, int nr, int bw, bool enh); - int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe); + u8 type; + u32 dcb; + u32 drive; + u32 sense; + u32 state; }; -#define nouveau_i2c_port_create(p,e,o,i,a,d) \ - nouveau_i2c_port_create_((p), (e), (o), (i), (a), \ - sizeof(**d), (void **)d) -#define nouveau_i2c_port_destroy(p) ({ \ - struct nouveau_i2c_port *port = (p); \ - _nouveau_i2c_port_dtor(nv_object(i2c)); \ -}) -#define nouveau_i2c_port_init(p) \ - nouveau_object_init(&(p)->base) -#define nouveau_i2c_port_fini(p,s) \ - nouveau_object_fini(&(p)->base, (s)) - -int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, u8, - const struct i2c_algorithm *, int, void **); -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 { 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 i2c_board_info *, bool (*match)(struct nouveau_i2c_port *, @@ -76,76 +40,21 @@ nouveau_i2c(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_I2C]; } -#define nouveau_i2c_create(p,e,o,s,d) \ - nouveau_i2c_create_((p), (e), (o), (s), sizeof(**d), (void **)d) -#define nouveau_i2c_destroy(p) ({ \ - struct nouveau_i2c *i2c = (p); \ - _nouveau_i2c_dtor(nv_object(i2c)); \ -}) -#define nouveau_i2c_init(p) ({ \ - struct nouveau_i2c *i2c = (p); \ - _nouveau_i2c_init(nv_object(i2c)); \ -}) -#define nouveau_i2c_fini(p,s) ({ \ - struct nouveau_i2c *i2c = (p); \ - _nouveau_i2c_fini(nv_object(i2c), (s)); \ -}) - -int nouveau_i2c_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, struct nouveau_oclass *, - int, void **); -void _nouveau_i2c_dtor(struct nouveau_object *); -int _nouveau_i2c_init(struct nouveau_object *); -int _nouveau_i2c_fini(struct nouveau_object *, bool); - -extern struct nouveau_oclass nv04_i2c_oclass; -extern struct nouveau_oclass nv4e_i2c_oclass; -extern struct nouveau_oclass nv50_i2c_oclass; -extern struct nouveau_oclass nv94_i2c_oclass; -extern struct nouveau_oclass nvd0_i2c_oclass; -extern struct nouveau_oclass nouveau_anx9805_sclass[]; - -extern const struct i2c_algorithm nouveau_i2c_bit_algo; -extern const struct i2c_algorithm nouveau_i2c_aux_algo; - -static inline int -nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg) -{ - u8 val; - struct i2c_msg msgs[] = { - { .addr = addr, .flags = 0, .len = 1, .buf = ® }, - { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val }, - }; - - int ret = i2c_transfer(&port->adapter, msgs, 2); - if (ret != 2) - return -EIO; - - return val; -} - -static inline int -nv_wri2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg, u8 val) -{ - u8 buf[2] = { reg, val }; - struct i2c_msg msgs[] = { - { .addr = addr, .flags = 0, .len = 2, .buf = buf }, - }; - - int ret = i2c_transfer(&port->adapter, msgs, 1); - if (ret != 1) - return -EIO; +extern struct nouveau_oclass nouveau_i2c_oclass; - return 0; -} +void nouveau_i2c_drive_scl(void *, int); +void nouveau_i2c_drive_sda(void *, int); +int nouveau_i2c_sense_scl(void *); +int nouveau_i2c_sense_sda(void *); -static inline bool -nv_probe_i2c(struct nouveau_i2c_port *port, u8 addr) -{ - return nv_rdi2cr(port, addr, 0) >= 0; -} +int nv_rdi2cr(struct nouveau_i2c_port *, u8 addr, u8 reg); +int nv_wri2cr(struct nouveau_i2c_port *, u8 addr, u8 reg, u8 val); +bool nv_probe_i2c(struct nouveau_i2c_port *, u8 addr); int nv_rdaux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size); int nv_wraux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size); +extern const struct i2c_algorithm nouveau_i2c_bit_algo; +extern const struct i2c_algorithm nouveau_i2c_aux_algo; + #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h index 6b17b614629f..faee569fd458 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -4,10 +4,10 @@ #include #include -enum nouveau_therm_mode { - NOUVEAU_THERM_CTRL_NONE = 0, - NOUVEAU_THERM_CTRL_MANUAL = 1, - NOUVEAU_THERM_CTRL_AUTO = 2, +enum nouveau_therm_fan_mode { + FAN_CONTROL_NONE = 0, + FAN_CONTROL_MANUAL = 1, + FAN_CONTROL_NR, }; enum nouveau_therm_attr_type { @@ -28,11 +28,6 @@ enum nouveau_therm_attr_type { struct nouveau_therm { struct nouveau_subdev base; - int (*pwm_ctrl)(struct nouveau_therm *, int line, bool); - int (*pwm_get)(struct nouveau_therm *, int line, u32 *, u32 *); - int (*pwm_set)(struct nouveau_therm *, int line, u32, u32); - int (*pwm_clock)(struct nouveau_therm *); - int (*fan_get)(struct nouveau_therm *); int (*fan_set)(struct nouveau_therm *, int); int (*fan_sense)(struct nouveau_therm *); @@ -51,29 +46,13 @@ nouveau_therm(void *obj) } #define nouveau_therm_create(p,e,o,d) \ - nouveau_therm_create_((p), (e), (o), sizeof(**d), (void **)d) -#define nouveau_therm_destroy(p) ({ \ - struct nouveau_therm *therm = (p); \ - _nouveau_therm_dtor(nv_object(therm)); \ -}) -#define nouveau_therm_init(p) ({ \ - struct nouveau_therm *therm = (p); \ - _nouveau_therm_init(nv_object(therm)); \ -}) -#define nouveau_therm_fini(p,s) ({ \ - struct nouveau_therm *therm = (p); \ - _nouveau_therm_init(nv_object(therm), (s)); \ -}) + nouveau_subdev_create((p), (e), (o), 0, "THERM", "therm", d) +#define nouveau_therm_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) -int nouveau_therm_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); -void _nouveau_therm_dtor(struct nouveau_object *); -int _nouveau_therm_init(struct nouveau_object *); -int _nouveau_therm_fini(struct nouveau_object *, bool); +#define _nouveau_therm_dtor _nouveau_subdev_dtor extern struct nouveau_oclass nv40_therm_oclass; extern struct nouveau_oclass nv50_therm_oclass; -extern struct nouveau_oclass nva3_therm_oclass; -extern struct nouveau_oclass nvd0_therm_oclass; #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/timer.h index e465d158d352..c24ec8ab3db4 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/timer.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/timer.h @@ -10,14 +10,6 @@ struct nouveau_alarm { void (*func)(struct nouveau_alarm *); }; -static inline void -nouveau_alarm_init(struct nouveau_alarm *alarm, - void (*func)(struct nouveau_alarm *)) -{ - INIT_LIST_HEAD(&alarm->head); - alarm->func = func; -} - bool nouveau_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data); bool nouveau_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data); bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data); diff --git a/trunk/drivers/gpu/drm/nouveau/core/os.h b/trunk/drivers/gpu/drm/nouveau/core/os.h index eb496033b55c..cfe3b9cad156 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/os.h +++ b/trunk/drivers/gpu/drm/nouveau/core/os.h @@ -16,7 +16,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index e816f06637a7..f621f69fa1a2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c @@ -172,7 +172,7 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) nv_wr32(bios, pcireg, access); } -#if defined(CONFIG_ACPI) && defined(CONFIG_X86) +#if defined(CONFIG_ACPI) int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); bool nouveau_acpi_rom_supported(struct pci_dev *pdev); #else diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index 2d9b9d7a7992..0fd87df99dd6 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c @@ -107,18 +107,6 @@ dcb_outp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) return 0x0000; } -static inline u16 -dcb_outp_hasht(struct dcb_output *outp) -{ - return (outp->extdev << 8) | (outp->location << 4) | outp->type; -} - -static inline u16 -dcb_outp_hashm(struct dcb_output *outp) -{ - return (outp->heads << 8) | (outp->link << 6) | outp->or; -} - u16 dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len, struct dcb_output *outp) @@ -147,28 +135,34 @@ dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len, case DCB_OUTPUT_DP: outp->link = (conf & 0x00000030) >> 4; outp->sorconf.link = outp->link; /*XXX*/ - outp->extdev = 0x00; - if (outp->location != 0) - outp->extdev = (conf & 0x0000ff00) >> 8; break; default: break; } } - - outp->hasht = dcb_outp_hasht(outp); - outp->hashm = dcb_outp_hashm(outp); } return dcb; } +static inline u16 +dcb_outp_hasht(struct dcb_output *outp) +{ + return outp->type; +} + +static inline u16 +dcb_outp_hashm(struct dcb_output *outp) +{ + return (outp->heads << 8) | (outp->link << 6) | outp->or; +} + u16 dcb_outp_match(struct nouveau_bios *bios, u16 type, u16 mask, u8 *ver, u8 *len, struct dcb_output *outp) { u16 dcb, idx = 0; while ((dcb = dcb_outp_parse(bios, idx++, ver, len, outp))) { - if ((dcb_outp_hasht(outp) & 0x00ff) == (type & 0x00ff)) { + if (dcb_outp_hasht(outp) == type) { if ((dcb_outp_hashm(outp) & mask) == mask) break; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c index b2a676e53580..5afb568b2d69 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c @@ -48,7 +48,7 @@ extdev_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt) return extdev + *hdr; } -static u16 +u16 nvbios_extdev_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len) { u8 hdr, cnt; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c index 172a4f999990..c84e93fa6d95 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c @@ -25,7 +25,6 @@ #include #include #include -#include u16 dcb_gpio_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) @@ -61,14 +60,8 @@ dcb_gpio_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) u16 dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len) { - u8 hdr, cnt, xver; /* use gpio version for xpio entry parsing */ - u16 gpio; - - if (!idx--) - gpio = dcb_gpio_table(bios, ver, &hdr, &cnt, len); - else - gpio = dcb_xpio_table(bios, idx, &xver, &hdr, &cnt, len); - + u8 hdr, cnt; + u16 gpio = !idx ? dcb_gpio_table(bios, ver, &hdr, &cnt, len) : 0x0000; if (gpio && ent < cnt) return gpio + hdr + (ent * *len); return 0x0000; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c index cfb9288c6d28..ad577db83766 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c @@ -70,12 +70,12 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info) u8 ver, len; u16 ent = dcb_i2c_entry(bios, idx, &ver, &len); if (ent) { - info->type = nv_ro08(bios, ent + 3); - info->share = DCB_I2C_UNUSED; + info->data = nv_ro32(bios, ent + 0); + info->type = nv_ro08(bios, ent + 3); if (ver < 0x30) { info->type &= 0x07; if (info->type == 0x07) - info->type = DCB_I2C_UNUSED; + info->type = 0xff; } switch (info->type) { @@ -88,11 +88,7 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info) return 0; case DCB_I2C_NVIO_BIT: case DCB_I2C_NVIO_AUX: - info->drive = nv_ro08(bios, ent + 0) & 0x0f; - if (nv_ro08(bios, ent + 1) & 0x01) { - info->share = nv_ro08(bios, ent + 1) >> 1; - info->share &= 0x0f; - } + info->drive = nv_ro08(bios, ent + 0); return 0; case DCB_I2C_UNUSED: return 0; @@ -125,8 +121,7 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info) if (!info->sense) info->sense = 0x36; } - info->type = DCB_I2C_NV04_BIT; - info->share = DCB_I2C_UNUSED; + info->type = DCB_I2C_NV04_BIT; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 2cc1e6a5eb6a..690ed438b2ad 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -231,11 +231,6 @@ init_i2c(struct nvbios_init *init, int index) return NULL; } - if (index == -2 && init->outp->location) { - index = NV_I2C_TYPE_EXTAUX(init->outp->extdev); - return i2c->find_type(i2c, index); - } - index = init->outp->i2c_index; } @@ -263,7 +258,7 @@ init_wri2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg, u8 val) static int init_rdauxr(struct nvbios_init *init, u32 addr) { - struct nouveau_i2c_port *port = init_i2c(init, -2); + struct nouveau_i2c_port *port = init_i2c(init, -1); u8 data; if (port && init_exec(init)) { @@ -279,7 +274,7 @@ init_rdauxr(struct nvbios_init *init, u32 addr) static int init_wrauxr(struct nvbios_init *init, u32 addr, u8 data) { - struct nouveau_i2c_port *port = init_i2c(init, -2); + struct nouveau_i2c_port *port = init_i2c(init, -1); if (port && init_exec(init)) return nv_wraux(port, addr, &data, 1); return -ENODEV; @@ -1821,7 +1816,7 @@ init_ram_restrict_zm_reg_group(struct nvbios_init *init) u8 i, j; trace("RAM_RESTRICT_ZM_REG_GROUP\t" - "R[0x%08x] 0x%02x 0x%02x\n", addr, incr, num); + "R[%08x] 0x%02x 0x%02x\n", addr, incr, num); init->offset += 7; for (i = 0; i < num; i++) { @@ -1854,7 +1849,7 @@ init_copy_zm_reg(struct nvbios_init *init) u32 sreg = nv_ro32(bios, init->offset + 1); u32 dreg = nv_ro32(bios, init->offset + 5); - trace("COPY_ZM_REG\tR[0x%06x] = R[0x%06x]\n", dreg, sreg); + trace("COPY_ZM_REG\tR[0x%06x] = R[0x%06x]\n", sreg, dreg); init->offset += 9; init_wr32(init, dreg, init_rd32(init, sreg)); @@ -1871,7 +1866,7 @@ init_zm_reg_group(struct nvbios_init *init) u32 addr = nv_ro32(bios, init->offset + 1); u8 count = nv_ro08(bios, init->offset + 5); - trace("ZM_REG_GROUP\tR[0x%06x] =\n", addr); + trace("ZM_REG_GROUP\tR[0x%06x] =\n"); init->offset += 6; while (count--) { diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c index 22a20573ed1b..862a08a2ae27 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c @@ -55,7 +55,7 @@ therm_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt) return therm + nv_ro08(bios, therm + 1); } -static u16 +u16 nvbios_therm_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len) { u8 hdr, cnt; @@ -155,15 +155,10 @@ int nvbios_therm_fan_parse(struct nouveau_bios *bios, struct nvbios_therm_fan *fan) { - struct nouveau_therm_trip_point *cur_trip = NULL; u8 ver, len, i; u16 entry; - uint8_t duty_lut[] = { 0, 0, 25, 0, 40, 0, 50, 0, - 75, 0, 85, 0, 100, 0, 100, 0 }; - i = 0; - fan->nr_fan_trip = 0; while ((entry = nvbios_therm_entry(bios, i++, &ver, &len))) { s16 value = nv_ro16(bios, entry + 1); @@ -172,30 +167,9 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios, fan->min_duty = value & 0xff; fan->max_duty = (value & 0xff00) >> 8; break; - case 0x24: - fan->nr_fan_trip++; - cur_trip = &fan->trip[fan->nr_fan_trip - 1]; - cur_trip->hysteresis = value & 0xf; - cur_trip->temp = (value & 0xff0) >> 4; - cur_trip->fan_duty = duty_lut[(value & 0xf000) >> 12]; - break; - case 0x25: - cur_trip = &fan->trip[fan->nr_fan_trip - 1]; - cur_trip->fan_duty = value; - break; case 0x26: fan->pwm_freq = value; break; - case 0x3b: - fan->bump_period = value; - break; - case 0x3c: - fan->slow_down_period = value; - break; - case 0x46: - fan->linear_min_temp = nv_ro08(bios, entry + 1); - fan->linear_max_temp = nv_ro08(bios, entry + 2); - break; } } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/xpio.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/xpio.c deleted file mode 100644 index e9b8e5d30a7a..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/xpio.c +++ /dev/null @@ -1,76 +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 -#include -#include - -static u16 -dcb_xpiod_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - u16 data = dcb_gpio_table(bios, ver, hdr, cnt, len); - if (data && *ver >= 0x40 && *hdr >= 0x06) { - u16 xpio = nv_ro16(bios, data + 0x04); - if (xpio) { - *ver = nv_ro08(bios, data + 0x00); - *hdr = nv_ro08(bios, data + 0x01); - *cnt = nv_ro08(bios, data + 0x02); - *len = nv_ro08(bios, data + 0x03); - return xpio; - } - } - return 0x0000; -} - -u16 -dcb_xpio_table(struct nouveau_bios *bios, u8 idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - u16 data = dcb_xpiod_table(bios, ver, hdr, cnt, len); - if (data && idx < *cnt) { - u16 xpio = nv_ro16(bios, data + *hdr + (idx * *len)); - if (xpio) { - *ver = nv_ro08(bios, data + 0x00); - *hdr = nv_ro08(bios, data + 0x01); - *cnt = nv_ro08(bios, data + 0x02); - *len = nv_ro08(bios, data + 0x03); - return xpio; - } - } - return 0x0000; -} - -u16 -dcb_xpio_parse(struct nouveau_bios *bios, u8 idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, - struct nvbios_xpio *info) -{ - u16 data = dcb_xpio_table(bios, idx, ver, hdr, cnt, len); - if (data && *len >= 6) { - info->type = nv_ro08(bios, data + 0x04); - info->addr = nv_ro08(bios, data + 0x05); - info->flags = nv_ro08(bios, data + 0x06); - } - return 0x0000; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c deleted file mode 100644 index 8c7f8057a185..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c +++ /dev/null @@ -1,95 +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 - * Ben Skeggs - */ - -#include - -struct nv04_bus_priv { - struct nouveau_bus base; -}; - -static void -nv04_bus_intr(struct nouveau_subdev *subdev) -{ - struct nouveau_bus *pbus = nouveau_bus(subdev); - u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140); - - if (stat & 0x00000001) { - nv_error(pbus, "BUS ERROR\n"); - stat &= ~0x00000001; - nv_wr32(pbus, 0x001100, 0x00000001); - } - - if (stat & 0x00000110) { - subdev = nouveau_subdev(subdev, NVDEV_SUBDEV_GPIO); - if (subdev && subdev->intr) - subdev->intr(subdev); - stat &= ~0x00000110; - nv_wr32(pbus, 0x001100, 0x00000110); - } - - if (stat) { - nv_error(pbus, "unknown intr 0x%08x\n", stat); - nv_mask(pbus, 0x001140, stat, 0x00000000); - } -} - -static 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_priv *priv; - int ret; - - ret = nouveau_bus_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - nv_subdev(priv)->intr = nv04_bus_intr; - return 0; -} - -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, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c deleted file mode 100644 index 34132aef34e1..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.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 - * Ben Skeggs - */ - -#include - -struct nv31_bus_priv { - struct nouveau_bus base; -}; - -static void -nv31_bus_intr(struct nouveau_subdev *subdev) -{ - struct nouveau_bus *pbus = nouveau_bus(subdev); - u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140); - u32 gpio = nv_rd32(pbus, 0x001104) & nv_rd32(pbus, 0x001144); - - if (gpio) { - subdev = nouveau_subdev(pbus, NVDEV_SUBDEV_GPIO); - if (subdev && subdev->intr) - subdev->intr(subdev); - } - - if (stat & 0x00000008) { /* NV41- */ - u32 addr = nv_rd32(pbus, 0x009084); - u32 data = nv_rd32(pbus, 0x009088); - - nv_error(pbus, "MMIO %s of 0x%08x FAULT at 0x%06x\n", - (addr & 0x00000002) ? "write" : "read", data, - (addr & 0x00fffffc)); - - stat &= ~0x00000008; - nv_wr32(pbus, 0x001100, 0x00000008); - } - - if (stat & 0x00070000) { - subdev = nouveau_subdev(pbus, NVDEV_SUBDEV_THERM); - if (subdev && subdev->intr) - subdev->intr(subdev); - stat &= ~0x00070000; - nv_wr32(pbus, 0x001100, 0x00070000); - } - - if (stat) { - nv_error(pbus, "unknown intr 0x%08x\n", stat); - nv_mask(pbus, 0x001140, stat, 0x00000000); - } -} - -static int -nv31_bus_init(struct nouveau_object *object) -{ - struct nv31_bus_priv *priv = (void *)object; - int ret; - - ret = nouveau_bus_init(&priv->base); - if (ret) - return ret; - - nv_wr32(priv, 0x001100, 0xffffffff); - nv_wr32(priv, 0x001140, 0x00070008); - return 0; -} - -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, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c deleted file mode 100644 index f5b2117fa8c6..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c +++ /dev/null @@ -1,105 +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 - * Ben Skeggs - */ - -#include - -struct nv50_bus_priv { - struct nouveau_bus base; -}; - -static void -nv50_bus_intr(struct nouveau_subdev *subdev) -{ - struct nouveau_bus *pbus = nouveau_bus(subdev); - u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140); - - if (stat & 0x00000008) { - u32 addr = nv_rd32(pbus, 0x009084); - u32 data = nv_rd32(pbus, 0x009088); - - nv_error(pbus, "MMIO %s of 0x%08x FAULT at 0x%06x\n", - (addr & 0x00000002) ? "write" : "read", data, - (addr & 0x00fffffc)); - - stat &= ~0x00000008; - nv_wr32(pbus, 0x001100, 0x00000008); - } - - if (stat & 0x00010000) { - subdev = nouveau_subdev(pbus, NVDEV_SUBDEV_THERM); - if (subdev && subdev->intr) - subdev->intr(subdev); - stat &= ~0x00010000; - nv_wr32(pbus, 0x001100, 0x00010000); - } - - if (stat) { - nv_error(pbus, "unknown intr 0x%08x\n", stat); - nv_mask(pbus, 0x001140, stat, 0); - } -} - -static int -nv50_bus_init(struct nouveau_object *object) -{ - struct nv50_bus_priv *priv = (void *)object; - int ret; - - ret = nouveau_bus_init(&priv->base); - if (ret) - return ret; - - nv_wr32(priv, 0x001100, 0xffffffff); - nv_wr32(priv, 0x001140, 0x00010008); - return 0; -} - -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, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c deleted file mode 100644 index b192d6246363..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c +++ /dev/null @@ -1,101 +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 - * Ben Skeggs - */ - -#include - -struct nvc0_bus_priv { - struct nouveau_bus base; -}; - -static void -nvc0_bus_intr(struct nouveau_subdev *subdev) -{ - struct nouveau_bus *pbus = nouveau_bus(subdev); - u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140); - - if (stat & 0x0000000e) { - u32 addr = nv_rd32(pbus, 0x009084); - u32 data = nv_rd32(pbus, 0x009088); - - nv_error(pbus, "MMIO %s of 0x%08x FAULT at 0x%06x [ %s%s%s]\n", - (addr & 0x00000002) ? "write" : "read", data, - (addr & 0x00fffffc), - (stat & 0x00000002) ? "!ENGINE " : "", - (stat & 0x00000004) ? "IBUS " : "", - (stat & 0x00000008) ? "TIMEOUT " : ""); - - nv_wr32(pbus, 0x009084, 0x00000000); - nv_wr32(pbus, 0x001100, (stat & 0x0000000e)); - stat &= ~0x0000000e; - } - - if (stat) { - nv_error(pbus, "unknown intr 0x%08x\n", stat); - nv_mask(pbus, 0x001140, stat, 0x00000000); - } -} - -static int -nvc0_bus_init(struct nouveau_object *object) -{ - struct nvc0_bus_priv *priv = (void *)object; - int ret; - - ret = nouveau_bus_init(&priv->base); - if (ret) - return ret; - - nv_wr32(priv, 0x001100, 0xffffffff); - nv_wr32(priv, 0x001140, 0x0000000e); - return 0; -} - -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, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/base.c index 3937ced5c753..f8a7ed4166cf 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/base.c @@ -66,7 +66,6 @@ static const u64 disable_map[] = { [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_DISABLE_CORE, [NVDEV_SUBDEV_MXM] = NV_DEVICE_DISABLE_CORE, [NVDEV_SUBDEV_MC] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_BUS] = NV_DEVICE_DISABLE_CORE, [NVDEV_SUBDEV_TIMER] = NV_DEVICE_DISABLE_CORE, [NVDEV_SUBDEV_FB] = NV_DEVICE_DISABLE_CORE, [NVDEV_SUBDEV_LTCG] = NV_DEVICE_DISABLE_CORE, @@ -104,8 +103,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent, struct nouveau_device *device; struct nouveau_devobj *devobj; struct nv_device_class *args = data; - u32 boot0, strap; - u64 disable, mmio_base, mmio_size; + u64 disable, boot0, strap; + u64 mmio_base, mmio_size; void __iomem *map; int ret, i, c; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c index 473c5c03d3c9..8626d0d6cbbc 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -47,11 +46,10 @@ nv04_identify(struct nouveau_device *device) case 0x04: device->cname = "NV04"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -65,11 +63,10 @@ nv04_identify(struct nouveau_device *device) case 0x05: device->cname = "NV05"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c index d0774f5bebe1..9c40b0fb23f6 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -49,11 +48,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "NV10"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -66,11 +64,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "NV15"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -85,11 +82,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "NV16"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -104,11 +100,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "nForce"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv1a_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -123,11 +118,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "NV11"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -142,11 +136,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "NV17"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -161,11 +154,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "nForce2"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv1a_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -180,11 +172,10 @@ nv10_identify(struct nouveau_device *device) device->cname = "NV18"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c index ab920e0dc45b..74f88f48e1c2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -50,11 +49,10 @@ nv20_identify(struct nouveau_device *device) device->cname = "NV20"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -69,11 +67,10 @@ nv20_identify(struct nouveau_device *device) device->cname = "NV25"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -88,11 +85,10 @@ nv20_identify(struct nouveau_device *device) device->cname = "NV28"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -107,11 +103,10 @@ nv20_identify(struct nouveau_device *device) device->cname = "NV2A"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c index 5f2110261b04..0ac1b2c4f61d 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -50,11 +49,10 @@ nv30_identify(struct nouveau_device *device) device->cname = "NV30"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -69,11 +67,10 @@ nv30_identify(struct nouveau_device *device) device->cname = "NV35"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv35_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -88,11 +85,10 @@ nv30_identify(struct nouveau_device *device) device->cname = "NV31"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -108,11 +104,10 @@ nv30_identify(struct nouveau_device *device) device->cname = "NV36"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv36_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; @@ -128,11 +123,10 @@ nv30_identify(struct nouveau_device *device) device->cname = "NV34"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c index f3d55efe9ac9..41d59689a021 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c @@ -24,8 +24,6 @@ #include #include -#include -#include #include #include #include @@ -52,12 +50,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "NV40"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -73,12 +70,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "NV41"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -94,12 +90,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "NV42"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -115,12 +110,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "NV43"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -136,12 +130,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "NV45"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -157,12 +150,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "G70"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -178,12 +170,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "G71"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -199,12 +190,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "G73"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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 ] = &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_INSTMEM] = &nv40_instmem_oclass; @@ -220,12 +210,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "NV44"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv44_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; @@ -241,12 +230,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "G72"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; @@ -262,12 +250,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "NV44A"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv44_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; @@ -283,12 +270,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "C61"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; @@ -304,12 +290,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "C51"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv4e_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv4e_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; @@ -325,12 +310,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "C73"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; @@ -346,12 +330,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "C67"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; @@ -367,12 +350,11 @@ nv40_identify(struct nouveau_device *device) device->cname = "C68"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; 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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c index 5ed2fa51ddc2..6ccfd8585ba2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -58,13 +57,12 @@ nv50_identify(struct nouveau_device *device) device->cname = "G80"; 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_I2C ] = &nouveau_i2c_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; @@ -81,13 +79,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; @@ -107,13 +104,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; @@ -133,13 +129,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; @@ -159,13 +154,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; @@ -185,13 +179,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; @@ -211,13 +204,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; @@ -237,13 +229,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; @@ -263,13 +254,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; @@ -289,13 +279,12 @@ nv50_identify(struct nouveau_device *device) 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_I2C ] = &nouveau_i2c_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; @@ -315,13 +304,12 @@ nv50_identify(struct nouveau_device *device) device->cname = "GT215"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; @@ -342,13 +330,12 @@ nv50_identify(struct nouveau_device *device) device->cname = "GT216"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; @@ -368,13 +355,12 @@ nv50_identify(struct nouveau_device *device) device->cname = "GT218"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; @@ -394,13 +380,12 @@ nv50_identify(struct nouveau_device *device) device->cname = "MCP89"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &nv98_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_INSTMEM] = &nv50_instmem_oclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c index 4393eb4d6564..f0461685a422 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -58,13 +57,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF100"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -87,13 +85,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF104"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -116,13 +113,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF106"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -145,13 +141,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF114"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -174,13 +169,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF116"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -203,13 +197,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF108"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -232,13 +225,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF110"; 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_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -261,13 +253,12 @@ nvc0_identify(struct nouveau_device *device) device->cname = "GF119"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -291,4 +282,4 @@ nvc0_identify(struct nouveau_device *device) } return 0; - } +} diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c index 5c12391619fd..03a652876e73 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -57,14 +56,13 @@ nve0_identify(struct nouveau_device *device) case 0xe4: device->cname = "GK104"; 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_GPIO ] = &nvd0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -86,14 +84,13 @@ nve0_identify(struct nouveau_device *device) 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_GPIO ] = &nvd0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; @@ -115,14 +112,13 @@ nve0_identify(struct nouveau_device *device) 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_GPIO ] = &nvd0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; - device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_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 ] = &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_LTCG ] = &nvc0_ltcg_oclass; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c index 4a8577838417..ae7249b09797 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c @@ -78,13 +78,12 @@ nv50_devinit_init(struct nouveau_object *object) if (ret) return ret; - /* if we ran the init tables, we have to execute the first script - * pointer of each dcb entry's display encoder table in order - * to properly initialise each encoder. + /* if we ran the init tables, execute first script pointer for each + * display table output entry that has a matching dcb entry. */ - while (priv->base.post && dcb_outp_parse(bios, i, &ver, &hdr, &outp)) { - if (nvbios_outp_match(bios, outp.hasht, outp.hashm, - &ver, &hdr, &cnt, &len, &info)) { + while (priv->base.post && ver) { + u16 data = nvbios_outp_parse(bios, i++, &ver, &hdr, &cnt, &len, &info); + if (data && dcb_outp_match(bios, info.type, info.mask, &ver, &len, &outp)) { struct nvbios_init init = { .subdev = nv_subdev(priv), .bios = bios, @@ -96,8 +95,7 @@ nv50_devinit_init(struct nouveau_object *object) nvbios_exec(&init); } - i++; - } + }; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index a4338d92b02e..487cb8c6c204 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c @@ -22,10 +22,8 @@ * Authors: Ben Skeggs */ -#include -#include -#include #include +#include #include #include @@ -304,18 +302,17 @@ static const struct nouveau_enum vm_client[] = { }; static const struct nouveau_enum vm_engine[] = { - { 0x00000000, "PGRAPH", NULL, NVDEV_ENGINE_GR }, - { 0x00000001, "PVP", NULL, NVDEV_ENGINE_VP }, + { 0x00000000, "PGRAPH", NULL }, + { 0x00000001, "PVP", NULL }, { 0x00000004, "PEEPHOLE", NULL }, - { 0x00000005, "PFIFO", vm_pfifo_subclients, NVDEV_ENGINE_FIFO }, + { 0x00000005, "PFIFO", vm_pfifo_subclients }, { 0x00000006, "BAR", vm_bar_subclients }, - { 0x00000008, "PPPP", NULL, NVDEV_ENGINE_PPP }, - { 0x00000008, "PMPEG", NULL, NVDEV_ENGINE_MPEG }, - { 0x00000009, "PBSP", NULL, NVDEV_ENGINE_BSP }, - { 0x0000000a, "PCRYPT", NULL, NVDEV_ENGINE_CRYPT }, + { 0x00000008, "PPPP", NULL }, + { 0x00000009, "PBSP", NULL }, + { 0x0000000a, "PCRYPT", NULL }, { 0x0000000b, "PCOUNTER", NULL }, { 0x0000000c, "SEMAPHORE_BG", NULL }, - { 0x0000000d, "PCOPY", NULL, NVDEV_ENGINE_COPY0 }, + { 0x0000000d, "PCOPY", NULL }, { 0x0000000e, "PDAEMON", NULL }, {} }; @@ -337,10 +334,8 @@ static void nv50_fb_intr(struct nouveau_subdev *subdev) { struct nouveau_device *device = nv_device(subdev); - struct nouveau_engine *engine; struct nv50_fb_priv *priv = (void *)subdev; const struct nouveau_enum *en, *cl; - struct nouveau_object *engctx = NULL; u32 trap[6], idx, chan; u8 st0, st1, st2, st3; int i; @@ -371,55 +366,36 @@ nv50_fb_intr(struct nouveau_subdev *subdev) } chan = (trap[2] << 16) | trap[1]; - en = nouveau_enum_find(vm_engine, st0); - - if (en && en->data2) { - const struct nouveau_enum *orig_en = en; - while (en->name && en->value == st0 && en->data2) { - engine = nouveau_engine(subdev, en->data2); - if (engine) { - engctx = nouveau_engctx_get(engine, chan); - if (engctx) - break; - } - en++; - } - if (!engctx) - en = orig_en; - } - - nv_error(priv, "trapped %s at 0x%02x%04x%04x on channel 0x%08x [%s] ", + nv_error(priv, "trapped %s at 0x%02x%04x%04x on channel 0x%08x ", (trap[5] & 0x00000100) ? "read" : "write", - trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, chan, - nouveau_client_name(engctx)); - - nouveau_engctx_put(engctx); + trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, chan); + en = nouveau_enum_find(vm_engine, st0); if (en) - pr_cont("%s/", en->name); + printk("%s/", en->name); else - pr_cont("%02x/", st0); + printk("%02x/", st0); cl = nouveau_enum_find(vm_client, st2); if (cl) - pr_cont("%s/", cl->name); + printk("%s/", cl->name); else - pr_cont("%02x/", st2); + printk("%02x/", st2); if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3); else if (en && en->data) cl = nouveau_enum_find(en->data, st3); else cl = NULL; if (cl) - pr_cont("%s", cl->name); + printk("%s", cl->name); else - pr_cont("%02x", st3); + printk("%02x", st3); - pr_cont(" reason: "); + printk(" reason: "); en = nouveau_enum_find(vm_fault, st1); if (en) - pr_cont("%s\n", en->name); + printk("%s\n", en->name); else - pr_cont("0x%08x\n", st1); + printk("0x%08x\n", st1); } static int diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c index d422acc9af15..9fb0f9b92d49 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c @@ -102,19 +102,135 @@ nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line) return ret; } -void -_nouveau_gpio_dtor(struct nouveau_object *object) +static int +nouveau_gpio_irq(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, bool on) +{ + struct dcb_gpio_func func; + int ret; + + ret = nouveau_gpio_find(gpio, idx, tag, line, &func); + if (ret == 0) { + if (idx == 0 && gpio->irq_enable) + gpio->irq_enable(gpio, func.line, on); + else + ret = -ENODEV; + } + + return ret; +} + +struct gpio_isr { + struct nouveau_gpio *gpio; + struct list_head head; + struct work_struct work; + int idx; + struct dcb_gpio_func func; + void (*handler)(void *, int); + void *data; + bool inhibit; +}; + +static void +nouveau_gpio_isr_bh(struct work_struct *work) +{ + struct gpio_isr *isr = container_of(work, struct gpio_isr, work); + struct nouveau_gpio *gpio = isr->gpio; + unsigned long flags; + int state; + + state = nouveau_gpio_get(gpio, isr->idx, isr->func.func, + isr->func.line); + if (state >= 0) + isr->handler(isr->data, state); + + spin_lock_irqsave(&gpio->lock, flags); + isr->inhibit = false; + spin_unlock_irqrestore(&gpio->lock, flags); +} + +static void +nouveau_gpio_isr_run(struct nouveau_gpio *gpio, int idx, u32 line_mask) +{ + struct gpio_isr *isr; + + if (idx != 0) + return; + + spin_lock(&gpio->lock); + list_for_each_entry(isr, &gpio->isr, head) { + if (line_mask & (1 << isr->func.line)) { + if (isr->inhibit) + continue; + isr->inhibit = true; + schedule_work(&isr->work); + } + } + spin_unlock(&gpio->lock); +} + +static int +nouveau_gpio_isr_add(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, + void (*handler)(void *, int), void *data) +{ + struct gpio_isr *isr; + unsigned long flags; + int ret; + + isr = kzalloc(sizeof(*isr), GFP_KERNEL); + if (!isr) + return -ENOMEM; + + ret = nouveau_gpio_find(gpio, idx, tag, line, &isr->func); + if (ret) { + kfree(isr); + return ret; + } + + INIT_WORK(&isr->work, nouveau_gpio_isr_bh); + isr->gpio = gpio; + isr->handler = handler; + isr->data = data; + isr->idx = idx; + + spin_lock_irqsave(&gpio->lock, flags); + list_add(&isr->head, &gpio->isr); + spin_unlock_irqrestore(&gpio->lock, flags); + return 0; +} + +static void +nouveau_gpio_isr_del(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, + void (*handler)(void *, int), void *data) { - struct nouveau_gpio *gpio = (void *)object; - nouveau_event_destroy(&gpio->events); - nouveau_subdev_destroy(&gpio->base); + struct gpio_isr *isr, *tmp; + struct dcb_gpio_func func; + unsigned long flags; + LIST_HEAD(tofree); + int ret; + + ret = nouveau_gpio_find(gpio, idx, tag, line, &func); + if (ret == 0) { + spin_lock_irqsave(&gpio->lock, flags); + list_for_each_entry_safe(isr, tmp, &gpio->isr, head) { + if (memcmp(&isr->func, &func, sizeof(func)) || + isr->idx != idx || + isr->handler != handler || isr->data != data) + continue; + list_move_tail(&isr->head, &tofree); + } + spin_unlock_irqrestore(&gpio->lock, flags); + + list_for_each_entry_safe(isr, tmp, &tofree, head) { + flush_work(&isr->work); + kfree(isr); + } + } } int nouveau_gpio_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int lines, - int length, void **pobject) + struct nouveau_oclass *oclass, int length, void **pobject) { struct nouveau_gpio *gpio; int ret; @@ -125,13 +241,15 @@ nouveau_gpio_create_(struct nouveau_object *parent, if (ret) return ret; - ret = nouveau_event_create(lines, &gpio->events); - if (ret) - return ret; - gpio->find = nouveau_gpio_find; gpio->set = nouveau_gpio_set; gpio->get = nouveau_gpio_get; + gpio->irq = nouveau_gpio_irq; + gpio->isr_run = nouveau_gpio_isr_run; + gpio->isr_add = nouveau_gpio_isr_add; + gpio->isr_del = nouveau_gpio_isr_del; + INIT_LIST_HEAD(&gpio->isr); + spin_lock_init(&gpio->lock); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c index 76d5d5465ddd..168d16a9a8e9 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c @@ -24,7 +24,7 @@ * */ -#include "priv.h" +#include struct nv10_gpio_priv { struct nouveau_gpio base; @@ -82,6 +82,15 @@ nv10_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) return 0; } +static void +nv10_gpio_irq_enable(struct nouveau_gpio *gpio, int line, bool on) +{ + u32 mask = 0x00010001 << line; + + nv_wr32(gpio, 0x001104, mask); + nv_mask(gpio, 0x001144, mask, on ? mask : 0); +} + static void nv10_gpio_intr(struct nouveau_subdev *subdev) { @@ -89,30 +98,12 @@ nv10_gpio_intr(struct nouveau_subdev *subdev) u32 intr = nv_rd32(priv, 0x001104); u32 hi = (intr & 0x0000ffff) >> 0; u32 lo = (intr & 0xffff0000) >> 16; - int i; - for (i = 0; (hi | lo) && i < 32; i++) { - if ((hi | lo) & (1 << i)) - nouveau_event_trigger(priv->base.events, i); - } + priv->base.isr_run(&priv->base, 0, hi | lo); nv_wr32(priv, 0x001104, intr); } -static void -nv10_gpio_intr_enable(struct nouveau_event *event, int line) -{ - nv_wr32(event->priv, 0x001104, 0x00010001 << line); - nv_mask(event->priv, 0x001144, 0x00010001 << line, 0x00010001 << line); -} - -static void -nv10_gpio_intr_disable(struct nouveau_event *event, int line) -{ - nv_wr32(event->priv, 0x001104, 0x00010001 << line); - nv_mask(event->priv, 0x001144, 0x00010001 << line, 0x00000000); -} - static int nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -121,16 +112,14 @@ nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv10_gpio_priv *priv; int ret; - ret = nouveau_gpio_create(parent, engine, oclass, 16, &priv); + ret = nouveau_gpio_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; priv->base.drive = nv10_gpio_drive; priv->base.sense = nv10_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nv10_gpio_intr_enable; - priv->base.events->disable = nv10_gpio_intr_disable; + priv->base.irq_enable = nv10_gpio_irq_enable; nv_subdev(priv)->intr = nv10_gpio_intr; return 0; } @@ -152,6 +141,8 @@ nv10_gpio_init(struct nouveau_object *object) if (ret) return ret; + nv_wr32(priv, 0x001140, 0x00000000); + nv_wr32(priv, 0x001100, 0xffffffff); nv_wr32(priv, 0x001144, 0x00000000); nv_wr32(priv, 0x001104, 0xffffffff); return 0; @@ -161,6 +152,7 @@ static int nv10_gpio_fini(struct nouveau_object *object, bool suspend) { struct nv10_gpio_priv *priv = (void *)object; + nv_wr32(priv, 0x001140, 0x00000000); nv_wr32(priv, 0x001144, 0x00000000); return nouveau_gpio_fini(&priv->base, suspend); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c index bf489dcf46e2..bf13a1200f26 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "priv.h" +#include struct nv50_gpio_priv { struct nouveau_gpio base; @@ -94,13 +94,22 @@ nv50_gpio_sense(struct nouveau_gpio *gpio, int line) return !!(nv_rd32(gpio, reg) & (4 << shift)); } +void +nv50_gpio_irq_enable(struct nouveau_gpio *gpio, int line, bool on) +{ + u32 reg = line < 16 ? 0xe050 : 0xe070; + u32 mask = 0x00010001 << (line & 0xf); + + nv_wr32(gpio, reg + 4, mask); + nv_mask(gpio, reg + 0, mask, on ? mask : 0); +} + void nv50_gpio_intr(struct nouveau_subdev *subdev) { struct nv50_gpio_priv *priv = (void *)subdev; u32 intr0, intr1 = 0; u32 hi, lo; - int i; intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050); if (nv_device(priv)->chipset >= 0x90) @@ -108,35 +117,13 @@ nv50_gpio_intr(struct nouveau_subdev *subdev) hi = (intr0 & 0x0000ffff) | (intr1 << 16); lo = (intr0 >> 16) | (intr1 & 0xffff0000); - - for (i = 0; (hi | lo) && i < 32; i++) { - if ((hi | lo) & (1 << i)) - nouveau_event_trigger(priv->base.events, i); - } + priv->base.isr_run(&priv->base, 0, hi | lo); nv_wr32(priv, 0xe054, intr0); if (nv_device(priv)->chipset >= 0x90) nv_wr32(priv, 0xe074, intr1); } -void -nv50_gpio_intr_enable(struct nouveau_event *event, int line) -{ - const u32 addr = line < 16 ? 0xe050 : 0xe070; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x04, mask); - nv_mask(event->priv, addr + 0x00, mask, mask); -} - -void -nv50_gpio_intr_disable(struct nouveau_event *event, int line) -{ - const u32 addr = line < 16 ? 0xe050 : 0xe070; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x04, mask); - nv_mask(event->priv, addr + 0x00, mask, 0x00000000); -} - static int nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -145,9 +132,7 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv50_gpio_priv *priv; int ret; - ret = nouveau_gpio_create(parent, engine, oclass, - nv_device(parent)->chipset >= 0x90 ? 32 : 16, - &priv); + ret = nouveau_gpio_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -155,9 +140,7 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->base.reset = nv50_gpio_reset; priv->base.drive = nv50_gpio_drive; priv->base.sense = nv50_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nv50_gpio_intr_enable; - priv->base.events->disable = nv50_gpio_intr_disable; + priv->base.irq_enable = nv50_gpio_irq_enable; nv_subdev(priv)->intr = nv50_gpio_intr; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c index 010431e3acec..83e8b8f16e6a 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c @@ -22,13 +22,13 @@ * Authors: Ben Skeggs */ -#include "priv.h" +#include struct nvd0_gpio_priv { struct nouveau_gpio base; }; -void +static void nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match) { struct nouveau_bios *bios = nouveau_bios(gpio); @@ -57,7 +57,7 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match) } } -int +static int nvd0_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) { u32 data = ((dir ^ 1) << 13) | (out << 12); @@ -66,7 +66,7 @@ nvd0_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) return 0; } -int +static int nvd0_gpio_sense(struct nouveau_gpio *gpio, int line) { return !!(nv_rd32(gpio, 0x00d610 + (line * 4)) & 0x00004000); @@ -80,7 +80,7 @@ nvd0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvd0_gpio_priv *priv; int ret; - ret = nouveau_gpio_create(parent, engine, oclass, 32, &priv); + ret = nouveau_gpio_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -88,9 +88,7 @@ nvd0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->base.reset = nvd0_gpio_reset; priv->base.drive = nvd0_gpio_drive; priv->base.sense = nvd0_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nv50_gpio_intr_enable; - priv->base.events->disable = nv50_gpio_intr_disable; + priv->base.irq_enable = nv50_gpio_irq_enable; nv_subdev(priv)->intr = nv50_gpio_intr; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c deleted file mode 100644 index 16b8c5bf5efa..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c +++ /dev/null @@ -1,131 +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 "priv.h" - -struct nve0_gpio_priv { - struct nouveau_gpio base; -}; - -void -nve0_gpio_intr(struct nouveau_subdev *subdev) -{ - struct nve0_gpio_priv *priv = (void *)subdev; - u32 intr0 = nv_rd32(priv, 0xdc00) & nv_rd32(priv, 0xdc08); - u32 intr1 = nv_rd32(priv, 0xdc80) & nv_rd32(priv, 0xdc88); - u32 hi = (intr0 & 0x0000ffff) | (intr1 << 16); - u32 lo = (intr0 >> 16) | (intr1 & 0xffff0000); - int i; - - for (i = 0; (hi | lo) && i < 32; i++) { - if ((hi | lo) & (1 << i)) - nouveau_event_trigger(priv->base.events, i); - } - - nv_wr32(priv, 0xdc00, intr0); - nv_wr32(priv, 0xdc88, intr1); -} - -void -nve0_gpio_intr_enable(struct nouveau_event *event, int line) -{ - const u32 addr = line < 16 ? 0xdc00 : 0xdc80; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x08, mask); - nv_mask(event->priv, addr + 0x00, mask, mask); -} - -void -nve0_gpio_intr_disable(struct nouveau_event *event, int line) -{ - const u32 addr = line < 16 ? 0xdc00 : 0xdc80; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x08, mask); - nv_mask(event->priv, addr + 0x00, mask, 0x00000000); -} - -int -nve0_gpio_fini(struct nouveau_object *object, bool suspend) -{ - struct nve0_gpio_priv *priv = (void *)object; - nv_wr32(priv, 0xdc08, 0x00000000); - nv_wr32(priv, 0xdc88, 0x00000000); - return nouveau_gpio_fini(&priv->base, suspend); -} - -int -nve0_gpio_init(struct nouveau_object *object) -{ - struct nve0_gpio_priv *priv = (void *)object; - int ret; - - ret = nouveau_gpio_init(&priv->base); - if (ret) - return ret; - - nv_wr32(priv, 0xdc00, 0xffffffff); - nv_wr32(priv, 0xdc80, 0xffffffff); - return 0; -} - -void -nve0_gpio_dtor(struct nouveau_object *object) -{ - struct nve0_gpio_priv *priv = (void *)object; - nouveau_gpio_destroy(&priv->base); -} - -static int -nve0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nve0_gpio_priv *priv; - int ret; - - ret = nouveau_gpio_create(parent, engine, oclass, 32, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.reset = nvd0_gpio_reset; - priv->base.drive = nvd0_gpio_drive; - priv->base.sense = nvd0_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nve0_gpio_intr_enable; - priv->base.events->disable = nve0_gpio_intr_disable; - nv_subdev(priv)->intr = nve0_gpio_intr; - return 0; -} - -struct nouveau_oclass -nve0_gpio_oclass = { - .handle = NV_SUBDEV(GPIO, 0xe0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nve0_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nve0_gpio_init, - .fini = nve0_gpio_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h b/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h deleted file mode 100644 index 2ee1c895c782..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __NVKM_GPIO_H__ -#define __NVKM_GPIO_H__ - -#include - -void nv50_gpio_dtor(struct nouveau_object *); -int nv50_gpio_init(struct nouveau_object *); -int nv50_gpio_fini(struct nouveau_object *, bool); -void nv50_gpio_intr(struct nouveau_subdev *); -void nv50_gpio_intr_enable(struct nouveau_event *, int line); -void nv50_gpio_intr_disable(struct nouveau_event *, int line); - -void nvd0_gpio_reset(struct nouveau_gpio *, u8); -int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int); -int nvd0_gpio_sense(struct nouveau_gpio *, int); - -#endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c deleted file mode 100644 index dec94e9d776a..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c +++ /dev/null @@ -1,279 +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 - -struct anx9805_i2c_port { - struct nouveau_i2c_port base; - u32 addr; - u32 ctrl; -}; - -static int -anx9805_train(struct nouveau_i2c_port *port, int link_nr, int link_bw, bool enh) -{ - struct anx9805_i2c_port *chan = (void *)port; - struct nouveau_i2c_port *mast = (void *)nv_object(chan)->parent; - u8 tmp, i; - - nv_wri2cr(mast, chan->addr, 0xa0, link_bw); - nv_wri2cr(mast, chan->addr, 0xa1, link_nr | (enh ? 0x80 : 0x00)); - nv_wri2cr(mast, chan->addr, 0xa2, 0x01); - nv_wri2cr(mast, chan->addr, 0xa8, 0x01); - - i = 0; - while ((tmp = nv_rdi2cr(mast, chan->addr, 0xa8)) & 0x01) { - mdelay(5); - if (i++ == 100) { - nv_error(port, "link training timed out\n"); - return -ETIMEDOUT; - } - } - - if (tmp & 0x70) { - nv_error(port, "link training failed: 0x%02x\n", tmp); - return -EIO; - } - - return 1; -} - -static int -anx9805_aux(struct nouveau_i2c_port *port, u8 type, u32 addr, u8 *data, u8 size) -{ - struct anx9805_i2c_port *chan = (void *)port; - struct nouveau_i2c_port *mast = (void *)nv_object(chan)->parent; - int i, ret = -ETIMEDOUT; - u8 tmp; - - tmp = nv_rdi2cr(mast, chan->ctrl, 0x07) & ~0x04; - nv_wri2cr(mast, chan->ctrl, 0x07, tmp | 0x04); - nv_wri2cr(mast, chan->ctrl, 0x07, tmp); - nv_wri2cr(mast, chan->ctrl, 0xf7, 0x01); - - nv_wri2cr(mast, chan->addr, 0xe4, 0x80); - for (i = 0; !(type & 1) && i < size; i++) - nv_wri2cr(mast, chan->addr, 0xf0 + i, data[i]); - nv_wri2cr(mast, chan->addr, 0xe5, ((size - 1) << 4) | type); - nv_wri2cr(mast, chan->addr, 0xe6, (addr & 0x000ff) >> 0); - nv_wri2cr(mast, chan->addr, 0xe7, (addr & 0x0ff00) >> 8); - nv_wri2cr(mast, chan->addr, 0xe8, (addr & 0xf0000) >> 16); - nv_wri2cr(mast, chan->addr, 0xe9, 0x01); - - i = 0; - while ((tmp = nv_rdi2cr(mast, chan->addr, 0xe9)) & 0x01) { - mdelay(5); - if (i++ == 32) - goto done; - } - - if ((tmp = nv_rdi2cr(mast, chan->ctrl, 0xf7)) & 0x01) { - ret = -EIO; - goto done; - } - - for (i = 0; (type & 1) && i < size; i++) - data[i] = nv_rdi2cr(mast, chan->addr, 0xf0 + i); - ret = 0; -done: - nv_wri2cr(mast, chan->ctrl, 0xf7, 0x01); - return ret; -} - -static const struct nouveau_i2c_func -anx9805_aux_func = { - .aux = anx9805_aux, - .lnk_ctl = anx9805_train, -}; - -static int -anx9805_aux_chan_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct nouveau_i2c_port *mast = (void *)parent; - struct anx9805_i2c_port *chan; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_aux_algo, &chan); - *pobject = nv_object(chan); - if (ret) - return ret; - - switch ((oclass->handle & 0xff00) >> 8) { - case 0x0d: - chan->addr = 0x38; - chan->ctrl = 0x39; - break; - case 0x0e: - chan->addr = 0x3c; - chan->ctrl = 0x3b; - break; - default: - BUG_ON(1); - } - - if (mast->adapter.algo == &i2c_bit_algo) { - struct i2c_algo_bit_data *algo = mast->adapter.algo_data; - algo->udelay = max(algo->udelay, 40); - } - - chan->base.func = &anx9805_aux_func; - return 0; -} - -static struct nouveau_ofuncs -anx9805_aux_ofuncs = { - .ctor = anx9805_aux_chan_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = _nouveau_i2c_port_init, - .fini = _nouveau_i2c_port_fini, -}; - -static int -anx9805_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -{ - struct anx9805_i2c_port *port = adap->algo_data; - struct nouveau_i2c_port *mast = (void *)nv_object(port)->parent; - struct i2c_msg *msg = msgs; - int ret = -ETIMEDOUT; - int i, j, cnt = num; - u8 seg = 0x00, off = 0x00, tmp; - - tmp = nv_rdi2cr(mast, port->ctrl, 0x07) & ~0x10; - nv_wri2cr(mast, port->ctrl, 0x07, tmp | 0x10); - nv_wri2cr(mast, port->ctrl, 0x07, tmp); - nv_wri2cr(mast, port->addr, 0x43, 0x05); - mdelay(5); - - while (cnt--) { - if ( (msg->flags & I2C_M_RD) && msg->addr == 0x50) { - nv_wri2cr(mast, port->addr, 0x40, msg->addr << 1); - nv_wri2cr(mast, port->addr, 0x41, seg); - nv_wri2cr(mast, port->addr, 0x42, off); - nv_wri2cr(mast, port->addr, 0x44, msg->len); - nv_wri2cr(mast, port->addr, 0x45, 0x00); - nv_wri2cr(mast, port->addr, 0x43, 0x01); - for (i = 0; i < msg->len; i++) { - j = 0; - while (nv_rdi2cr(mast, port->addr, 0x46) & 0x10) { - mdelay(5); - if (j++ == 32) - goto done; - } - msg->buf[i] = nv_rdi2cr(mast, port->addr, 0x47); - } - } else - if (!(msg->flags & I2C_M_RD)) { - if (msg->addr == 0x50 && msg->len == 0x01) { - off = msg->buf[0]; - } else - if (msg->addr == 0x30 && msg->len == 0x01) { - seg = msg->buf[0]; - } else - goto done; - } else { - goto done; - } - msg++; - } - - ret = num; -done: - nv_wri2cr(mast, port->addr, 0x43, 0x00); - return ret; -} - -static u32 -anx9805_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm -anx9805_i2c_algo = { - .master_xfer = anx9805_xfer, - .functionality = anx9805_func -}; - -static const struct nouveau_i2c_func -anx9805_i2c_func = { -}; - -static int -anx9805_ddc_port_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct nouveau_i2c_port *mast = (void *)parent; - struct anx9805_i2c_port *port; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &anx9805_i2c_algo, &port); - *pobject = nv_object(port); - if (ret) - return ret; - - switch ((oclass->handle & 0xff00) >> 8) { - case 0x0d: - port->addr = 0x3d; - port->ctrl = 0x39; - break; - case 0x0e: - port->addr = 0x3f; - port->ctrl = 0x3b; - break; - default: - BUG_ON(1); - } - - if (mast->adapter.algo == &i2c_bit_algo) { - struct i2c_algo_bit_data *algo = mast->adapter.algo_data; - algo->udelay = max(algo->udelay, 40); - } - - port->base.func = &anx9805_i2c_func; - return 0; -} - -static struct nouveau_ofuncs -anx9805_ddc_ofuncs = { - .ctor = anx9805_ddc_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = _nouveau_i2c_port_init, - .fini = _nouveau_i2c_port_fini, -}; - -struct nouveau_oclass -nouveau_anx9805_sclass[] = { - { .handle = NV_I2C_TYPE_EXTDDC(0x0d), .ofuncs = &anx9805_ddc_ofuncs }, - { .handle = NV_I2C_TYPE_EXTAUX(0x0d), .ofuncs = &anx9805_aux_ofuncs }, - { .handle = NV_I2C_TYPE_EXTDDC(0x0e), .ofuncs = &anx9805_ddc_ofuncs }, - { .handle = NV_I2C_TYPE_EXTAUX(0x0e), .ofuncs = &anx9805_aux_ofuncs }, - {} -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c index 5de074ad170b..dc27e794a851 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c @@ -24,40 +24,151 @@ #include -int -nv_rdaux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size) +/****************************************************************************** + * aux channel util functions + *****************************************************************************/ +#define AUX_DBG(fmt, args...) nv_debug(aux, "AUXCH(%d): " fmt, ch, ##args) +#define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args) + +static void +auxch_fini(struct nouveau_i2c *aux, int ch) +{ + nv_mask(aux, 0x00e4e4 + (ch * 0x50), 0x00310000, 0x00000000); +} + +static int +auxch_init(struct nouveau_i2c *aux, int ch) +{ + const u32 unksel = 1; /* nfi which to use, or if it matters.. */ + const u32 ureq = unksel ? 0x00100000 : 0x00200000; + const u32 urep = unksel ? 0x01000000 : 0x02000000; + u32 ctrl, timeout; + + /* wait up to 1ms for any previous transaction to be done... */ + timeout = 1000; + do { + ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); + udelay(1); + if (!timeout--) { + AUX_ERR("begin idle timeout 0x%08x\n", ctrl); + return -EBUSY; + } + } while (ctrl & 0x03010000); + + /* set some magic, and wait up to 1ms for it to appear */ + nv_mask(aux, 0x00e4e4 + (ch * 0x50), 0x00300000, ureq); + timeout = 1000; + do { + ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); + udelay(1); + if (!timeout--) { + AUX_ERR("magic wait 0x%08x\n", ctrl); + auxch_fini(aux, ch); + return -EBUSY; + } + } while ((ctrl & 0x03000000) != urep); + + return 0; +} + +static int +auxch_tx(struct nouveau_i2c *aux, int ch, u8 type, u32 addr, u8 *data, u8 size) { - if (port->func->aux) { - if (port->func->acquire) - port->func->acquire(port); - return port->func->aux(port, 9, addr, data, size); + u32 ctrl, stat, timeout, retries; + u32 xbuf[4] = {}; + int ret, i; + + AUX_DBG("%d: 0x%08x %d\n", type, addr, size); + + ret = auxch_init(aux, ch); + if (ret) + goto out; + + stat = nv_rd32(aux, 0x00e4e8 + (ch * 0x50)); + if (!(stat & 0x10000000)) { + AUX_DBG("sink not detected\n"); + ret = -ENXIO; + goto out; } - return -ENODEV; + + if (!(type & 1)) { + memcpy(xbuf, data, size); + for (i = 0; i < 16; i += 4) { + AUX_DBG("wr 0x%08x\n", xbuf[i / 4]); + nv_wr32(aux, 0x00e4c0 + (ch * 0x50) + i, xbuf[i / 4]); + } + } + + ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); + ctrl &= ~0x0001f0ff; + ctrl |= type << 12; + ctrl |= size - 1; + nv_wr32(aux, 0x00e4e0 + (ch * 0x50), addr); + + /* retry transaction a number of times on failure... */ + ret = -EREMOTEIO; + for (retries = 0; retries < 32; retries++) { + /* reset, and delay a while if this is a retry */ + nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x80000000 | ctrl); + nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x00000000 | ctrl); + if (retries) + udelay(400); + + /* transaction request, wait up to 1ms for it to complete */ + nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x00010000 | ctrl); + + timeout = 1000; + do { + ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); + udelay(1); + if (!timeout--) { + AUX_ERR("tx req timeout 0x%08x\n", ctrl); + goto out; + } + } while (ctrl & 0x00010000); + + /* read status, and check if transaction completed ok */ + stat = nv_mask(aux, 0x00e4e8 + (ch * 0x50), 0, 0); + if (!(stat & 0x000f0f00)) { + ret = 0; + break; + } + + AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat); + } + + if (type & 1) { + for (i = 0; i < 16; i += 4) { + xbuf[i / 4] = nv_rd32(aux, 0x00e4d0 + (ch * 0x50) + i); + AUX_DBG("rd 0x%08x\n", xbuf[i / 4]); + } + memcpy(data, xbuf, size); + } + +out: + auxch_fini(aux, ch); + return ret; } int -nv_wraux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size) +nv_rdaux(struct nouveau_i2c_port *auxch, u32 addr, u8 *data, u8 size) { - if (port->func->aux) { - if (port->func->acquire) - port->func->acquire(port); - return port->func->aux(port, 8, addr, data, size); - } - return -ENODEV; + return auxch_tx(auxch->i2c, auxch->drive, 9, addr, data, size); +} + +int +nv_wraux(struct nouveau_i2c_port *auxch, u32 addr, u8 *data, u8 size) +{ + return auxch_tx(auxch->i2c, auxch->drive, 8, addr, data, size); } static int aux_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { - struct nouveau_i2c_port *port = adap->algo_data; + struct nouveau_i2c_port *auxch = (struct nouveau_i2c_port *)adap; struct i2c_msg *msg = msgs; int ret, mcnt = num; - if (!port->func->aux) - return -ENODEV; - if ( port->func->acquire) - port->func->acquire(port); - while (mcnt--) { u8 remaining = msg->len; u8 *ptr = msg->buf; @@ -74,7 +185,8 @@ aux_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (mcnt || remaining > 16) cmd |= 4; /* MOT */ - ret = port->func->aux(port, cmd, msg->addr, ptr, cnt); + ret = auxch_tx(auxch->i2c, auxch->drive, cmd, + msg->addr, ptr, cnt); if (ret < 0) return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index a114a0ed7e98..dbfc2abf0cfe 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -1,5 +1,5 @@ /* - * Copyright 2013 Red Hat Inc. + * 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"), @@ -22,136 +22,64 @@ * Authors: Ben Skeggs */ -#include +#include "core/option.h" -#include -#include -#include -#include -#include +#include "subdev/i2c.h" +#include "subdev/vga.h" -/****************************************************************************** - * interface to linux i2c bit-banging algorithm - *****************************************************************************/ - -#ifdef CONFIG_NOUVEAU_I2C_INTERNAL_DEFAULT -#define CSTMSEL true -#else -#define CSTMSEL false -#endif - -static int -nouveau_i2c_pre_xfer(struct i2c_adapter *adap) +int +nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg) { - struct i2c_algo_bit_data *bit = adap->algo_data; - struct nouveau_i2c_port *port = bit->data; - if (port->func->acquire) - port->func->acquire(port); - return 0; -} + u8 val; + struct i2c_msg msgs[] = { + { .addr = addr, .flags = 0, .len = 1, .buf = ® }, + { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val }, + }; -static void -nouveau_i2c_setscl(void *data, int state) -{ - struct nouveau_i2c_port *port = data; - port->func->drive_scl(port, state); -} + int ret = i2c_transfer(&port->adapter, msgs, 2); + if (ret != 2) + return -EIO; -static void -nouveau_i2c_setsda(void *data, int state) -{ - struct nouveau_i2c_port *port = data; - port->func->drive_sda(port, state); + return val; } -static int -nouveau_i2c_getscl(void *data) -{ - struct nouveau_i2c_port *port = data; - return port->func->sense_scl(port); -} - -static int -nouveau_i2c_getsda(void *data) +int +nv_wri2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg, u8 val) { - struct nouveau_i2c_port *port = data; - return port->func->sense_sda(port); -} + struct i2c_msg msgs[] = { + { .addr = addr, .flags = 0, .len = 1, .buf = ® }, + { .addr = addr, .flags = 0, .len = 1, .buf = &val }, + }; -/****************************************************************************** - * base i2c "port" class implementation - *****************************************************************************/ + int ret = i2c_transfer(&port->adapter, msgs, 2); + if (ret != 2) + return -EIO; -void -_nouveau_i2c_port_dtor(struct nouveau_object *object) -{ - struct nouveau_i2c_port *port = (void *)object; - i2c_del_adapter(&port->adapter); - nouveau_object_destroy(&port->base); + return 0; } -int -nouveau_i2c_port_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, u8 index, - const struct i2c_algorithm *algo, - int size, void **pobject) +bool +nv_probe_i2c(struct nouveau_i2c_port *port, u8 addr) { - struct nouveau_device *device = nv_device(parent); - struct nouveau_i2c *i2c = (void *)engine; - struct nouveau_i2c_port *port; - int ret; - - ret = nouveau_object_create_(parent, engine, oclass, 0, size, pobject); - port = *pobject; - if (ret) - return ret; - - snprintf(port->adapter.name, sizeof(port->adapter.name), - "nouveau-%s-%d", device->name, index); - port->adapter.owner = THIS_MODULE; - port->adapter.dev.parent = &device->pdev->dev; - port->index = index; - i2c_set_adapdata(&port->adapter, i2c); - - if ( algo == &nouveau_i2c_bit_algo && - !nouveau_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) { - struct i2c_algo_bit_data *bit; - - bit = kzalloc(sizeof(*bit), GFP_KERNEL); - if (!bit) - return -ENOMEM; - - bit->udelay = 10; - bit->timeout = usecs_to_jiffies(2200); - bit->data = port; - bit->pre_xfer = nouveau_i2c_pre_xfer; - bit->setsda = nouveau_i2c_setsda; - bit->setscl = nouveau_i2c_setscl; - bit->getsda = nouveau_i2c_getsda; - bit->getscl = nouveau_i2c_getscl; - - port->adapter.algo_data = bit; - ret = i2c_bit_add_bus(&port->adapter); - } else { - port->adapter.algo_data = port; - port->adapter.algo = algo; - ret = i2c_add_adapter(&port->adapter); - } - - /* drop port's i2c subdev refcount, i2c handles this itself */ - if (ret == 0) { - list_add_tail(&port->head, &i2c->ports); - atomic_dec(&engine->refcount); - } + u8 buf[] = { 0 }; + struct i2c_msg msgs[] = { + { + .addr = addr, + .flags = 0, + .len = 1, + .buf = buf, + }, + { + .addr = addr, + .flags = I2C_M_RD, + .len = 1, + .buf = buf, + } + }; - return ret; + return i2c_transfer(&port->adapter, msgs, 2) == 2; } -/****************************************************************************** - * base i2c subdev class implementation - *****************************************************************************/ - static struct nouveau_i2c_port * nouveau_i2c_find(struct nouveau_i2c *i2c, u8 index) { @@ -175,23 +103,29 @@ nouveau_i2c_find(struct nouveau_i2c *i2c, u8 index) list_for_each_entry(port, &i2c->ports, head) { if (port->index == index) - return port; + break; } - return NULL; -} + if (&port->head == &i2c->ports) + return NULL; -static struct nouveau_i2c_port * -nouveau_i2c_find_type(struct nouveau_i2c *i2c, u16 type) -{ - struct nouveau_i2c_port *port; + if (nv_device(i2c)->card_type >= NV_50 && (port->dcb & 0x00000100)) { + u32 reg = 0x00e500, val; + if (port->type == 6) { + reg += port->drive * 0x50; + val = 0x2002; + } else { + reg += ((port->dcb & 0x1e00) >> 9) * 0x50; + val = 0xe001; + } - list_for_each_entry(port, &i2c->ports, head) { - if (nv_hclass(port) == type) - return port; + /* nfi, but neither auxch or i2c work if it's 1 */ + nv_mask(i2c, reg + 0x0c, 0x00000001, 0x00000000); + /* nfi, but switches auxch vs normal i2c */ + nv_mask(i2c, reg + 0x00, 0x0000f003, val); } - return NULL; + return port; } static int @@ -221,86 +155,109 @@ nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, return -ENODEV; } -int -_nouveau_i2c_fini(struct nouveau_object *object, bool suspend) +void +nouveau_i2c_drive_scl(void *data, int state) { - struct nouveau_i2c *i2c = (void *)object; - struct nouveau_i2c_port *port; - int ret; + struct nouveau_i2c_port *port = data; - list_for_each_entry(port, &i2c->ports, head) { - ret = nv_ofuncs(port)->fini(nv_object(port), suspend); - if (ret && suspend) - goto fail; + if (port->type == DCB_I2C_NV04_BIT) { + u8 val = nv_rdvgac(port->i2c, 0, port->drive); + if (state) val |= 0x20; + else val &= 0xdf; + nv_wrvgac(port->i2c, 0, port->drive, val | 0x01); + } else + if (port->type == DCB_I2C_NV4E_BIT) { + nv_mask(port->i2c, port->drive, 0x2f, state ? 0x21 : 0x01); + } else + if (port->type == DCB_I2C_NVIO_BIT) { + if (state) port->state |= 0x01; + else port->state &= 0xfe; + nv_wr32(port->i2c, port->drive, 4 | port->state); } +} - return nouveau_subdev_fini(&i2c->base, suspend); -fail: - list_for_each_entry_continue_reverse(port, &i2c->ports, head) { - nv_ofuncs(port)->init(nv_object(port)); - } +void +nouveau_i2c_drive_sda(void *data, int state) +{ + struct nouveau_i2c_port *port = data; - return ret; + if (port->type == DCB_I2C_NV04_BIT) { + u8 val = nv_rdvgac(port->i2c, 0, port->drive); + if (state) val |= 0x10; + else val &= 0xef; + nv_wrvgac(port->i2c, 0, port->drive, val | 0x01); + } else + if (port->type == DCB_I2C_NV4E_BIT) { + nv_mask(port->i2c, port->drive, 0x1f, state ? 0x11 : 0x01); + } else + if (port->type == DCB_I2C_NVIO_BIT) { + if (state) port->state |= 0x02; + else port->state &= 0xfd; + nv_wr32(port->i2c, port->drive, 4 | port->state); + } } int -_nouveau_i2c_init(struct nouveau_object *object) +nouveau_i2c_sense_scl(void *data) { - struct nouveau_i2c *i2c = (void *)object; - struct nouveau_i2c_port *port; - int ret; - - ret = nouveau_subdev_init(&i2c->base); - if (ret == 0) { - list_for_each_entry(port, &i2c->ports, head) { - ret = nv_ofuncs(port)->init(nv_object(port)); - if (ret) - goto fail; - } - } - - return ret; -fail: - list_for_each_entry_continue_reverse(port, &i2c->ports, head) { - nv_ofuncs(port)->fini(nv_object(port), false); + struct nouveau_i2c_port *port = data; + struct nouveau_device *device = nv_device(port->i2c); + + if (port->type == DCB_I2C_NV04_BIT) { + return !!(nv_rdvgac(port->i2c, 0, port->sense) & 0x04); + } else + if (port->type == DCB_I2C_NV4E_BIT) { + return !!(nv_rd32(port->i2c, port->sense) & 0x00040000); + } else + if (port->type == DCB_I2C_NVIO_BIT) { + if (device->card_type < NV_D0) + return !!(nv_rd32(port->i2c, port->sense) & 0x01); + else + return !!(nv_rd32(port->i2c, port->sense) & 0x10); } - return ret; + return 0; } -void -_nouveau_i2c_dtor(struct nouveau_object *object) +int +nouveau_i2c_sense_sda(void *data) { - struct nouveau_i2c *i2c = (void *)object; - struct nouveau_i2c_port *port, *temp; - - list_for_each_entry_safe(port, temp, &i2c->ports, head) { - nouveau_object_ref(NULL, (struct nouveau_object **)&port); + struct nouveau_i2c_port *port = data; + struct nouveau_device *device = nv_device(port->i2c); + + if (port->type == DCB_I2C_NV04_BIT) { + return !!(nv_rdvgac(port->i2c, 0, port->sense) & 0x08); + } else + if (port->type == DCB_I2C_NV4E_BIT) { + return !!(nv_rd32(port->i2c, port->sense) & 0x00080000); + } else + if (port->type == DCB_I2C_NVIO_BIT) { + if (device->card_type < NV_D0) + return !!(nv_rd32(port->i2c, port->sense) & 0x02); + else + return !!(nv_rd32(port->i2c, port->sense) & 0x20); } - nouveau_subdev_destroy(&i2c->base); + return 0; } -static struct nouveau_oclass * -nouveau_i2c_extdev_sclass[] = { - nouveau_anx9805_sclass, +static const u32 nv50_i2c_port[] = { + 0x00e138, 0x00e150, 0x00e168, 0x00e180, + 0x00e254, 0x00e274, 0x00e764, 0x00e780, + 0x00e79c, 0x00e7b8 }; -int -nouveau_i2c_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, - struct nouveau_oclass *sclass, - int length, void **pobject) +static int +nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { + struct nouveau_device *device = nv_device(parent); struct nouveau_bios *bios = nouveau_bios(parent); + struct nouveau_i2c_port *port; struct nouveau_i2c *i2c; - struct nouveau_object *object; struct dcb_i2c_entry info; - int ret, i, j, index = -1; - struct dcb_output outp; - u8 ver, hdr; - u32 data; + int ret, i = -1; ret = nouveau_subdev_create(parent, engine, oclass, 0, "I2C", "i2c", &i2c); @@ -309,60 +266,142 @@ nouveau_i2c_create_(struct nouveau_object *parent, return ret; i2c->find = nouveau_i2c_find; - i2c->find_type = nouveau_i2c_find_type; i2c->identify = nouveau_i2c_identify; INIT_LIST_HEAD(&i2c->ports); - while (!dcb_i2c_parse(bios, ++index, &info)) { + while (!dcb_i2c_parse(bios, ++i, &info)) { if (info.type == DCB_I2C_UNUSED) continue; - oclass = sclass; - do { - ret = -EINVAL; - if (oclass->handle == info.type) { - ret = nouveau_object_ctor(*pobject, *pobject, - oclass, &info, - index, &object); - } - } while (ret && (++oclass)->handle); - } - - /* in addition to the busses specified in the i2c table, there - * may be ddc/aux channels hiding behind external tmds/dp/etc - * transmitters. - */ - index = ((index + 0x0f) / 0x10) * 0x10; - i = -1; - while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &outp))) { - if (!outp.location || !outp.extdev) - continue; + port = kzalloc(sizeof(*port), GFP_KERNEL); + if (!port) { + nv_error(i2c, "failed port memory alloc at %d\n", i); + break; + } - switch (outp.type) { - case DCB_OUTPUT_TMDS: - info.type = NV_I2C_TYPE_EXTDDC(outp.extdev); + port->type = info.type; + switch (port->type) { + case DCB_I2C_NV04_BIT: + port->drive = info.drive; + port->sense = info.sense; + break; + case DCB_I2C_NV4E_BIT: + port->drive = 0x600800 + info.drive; + port->sense = port->drive; + break; + case DCB_I2C_NVIO_BIT: + port->drive = info.drive & 0x0f; + if (device->card_type < NV_D0) { + if (port->drive >= ARRAY_SIZE(nv50_i2c_port)) + break; + port->drive = nv50_i2c_port[port->drive]; + port->sense = port->drive; + } else { + port->drive = 0x00d014 + (port->drive * 0x20); + port->sense = port->drive; + } break; - case DCB_OUTPUT_DP: - info.type = NV_I2C_TYPE_EXTAUX(outp.extdev); + case DCB_I2C_NVIO_AUX: + port->drive = info.drive & 0x0f; + port->sense = port->drive; + port->adapter.algo = &nouveau_i2c_aux_algo; break; default: + break; + } + + if (!port->adapter.algo && !port->drive) { + nv_error(i2c, "I2C%d: type %d index %x/%x unknown\n", + i, port->type, port->drive, port->sense); + kfree(port); continue; } - ret = -ENODEV; - j = -1; - while (ret && ++j < ARRAY_SIZE(nouveau_i2c_extdev_sclass)) { - parent = nv_object(i2c->find(i2c, outp.i2c_index)); - oclass = nouveau_i2c_extdev_sclass[j]; - do { - if (oclass->handle != info.type) - continue; - ret = nouveau_object_ctor(parent, *pobject, - oclass, NULL, - index++, &object); - } while (ret && (++oclass)->handle); + snprintf(port->adapter.name, sizeof(port->adapter.name), + "nouveau-%s-%d", device->name, i); + port->adapter.owner = THIS_MODULE; + port->adapter.dev.parent = &device->pdev->dev; + port->i2c = i2c; + port->index = i; + port->dcb = info.data; + i2c_set_adapdata(&port->adapter, i2c); + + if (port->adapter.algo != &nouveau_i2c_aux_algo) { + nouveau_i2c_drive_scl(port, 0); + nouveau_i2c_drive_sda(port, 1); + nouveau_i2c_drive_scl(port, 1); + +#ifdef CONFIG_NOUVEAU_I2C_INTERNAL_DEFAULT + if (nouveau_boolopt(device->cfgopt, "NvI2C", true)) { +#else + if (nouveau_boolopt(device->cfgopt, "NvI2C", false)) { +#endif + port->adapter.algo = &nouveau_i2c_bit_algo; + ret = i2c_add_adapter(&port->adapter); + } else { + port->adapter.algo_data = &port->bit; + port->bit.udelay = 10; + port->bit.timeout = usecs_to_jiffies(2200); + port->bit.data = port; + port->bit.setsda = nouveau_i2c_drive_sda; + port->bit.setscl = nouveau_i2c_drive_scl; + port->bit.getsda = nouveau_i2c_sense_sda; + port->bit.getscl = nouveau_i2c_sense_scl; + ret = i2c_bit_add_bus(&port->adapter); + } + } else { + port->adapter.algo = &nouveau_i2c_aux_algo; + ret = i2c_add_adapter(&port->adapter); + } + + if (ret) { + nv_error(i2c, "I2C%d: failed register: %d\n", i, ret); + kfree(port); + continue; } + + list_add_tail(&port->head, &i2c->ports); } return 0; } + +static void +nouveau_i2c_dtor(struct nouveau_object *object) +{ + struct nouveau_i2c *i2c = (void *)object; + struct nouveau_i2c_port *port, *temp; + + list_for_each_entry_safe(port, temp, &i2c->ports, head) { + i2c_del_adapter(&port->adapter); + list_del(&port->head); + kfree(port); + } + + nouveau_subdev_destroy(&i2c->base); +} + +static int +nouveau_i2c_init(struct nouveau_object *object) +{ + struct nouveau_i2c *i2c = (void *)object; + return nouveau_subdev_init(&i2c->base); +} + +static int +nouveau_i2c_fini(struct nouveau_object *object, bool suspend) +{ + struct nouveau_i2c *i2c = (void *)object; + return nouveau_subdev_fini(&i2c->base, suspend); +} + +struct nouveau_oclass +nouveau_i2c_oclass = { + .handle = NV_SUBDEV(I2C, 0x00), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nouveau_i2c_ctor, + .dtor = nouveau_i2c_dtor, + .init = nouveau_i2c_init, + .fini = nouveau_i2c_fini, + }, +}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c index a6e72d3b06b5..1c4c9a5c8e2e 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c @@ -32,25 +32,25 @@ static inline void i2c_drive_scl(struct nouveau_i2c_port *port, int state) { - port->func->drive_scl(port, state); + nouveau_i2c_drive_scl(port, state); } static inline void i2c_drive_sda(struct nouveau_i2c_port *port, int state) { - port->func->drive_sda(port, state); + nouveau_i2c_drive_sda(port, state); } static inline int i2c_sense_scl(struct nouveau_i2c_port *port) { - return port->func->sense_scl(port); + return nouveau_i2c_sense_scl(port); } static inline int i2c_sense_sda(struct nouveau_i2c_port *port) { - return port->func->sense_sda(port); + return nouveau_i2c_sense_sda(port); } static void @@ -77,8 +77,9 @@ i2c_start(struct nouveau_i2c_port *port) { int ret = 0; - if (!i2c_sense_scl(port) || - !i2c_sense_sda(port)) { + port->state = i2c_sense_scl(port); + port->state |= i2c_sense_sda(port) << 1; + if (port->state != 3) { i2c_drive_scl(port, 0); i2c_drive_sda(port, 1); if (!i2c_raise_scl(port)) @@ -183,13 +184,10 @@ i2c_addr(struct nouveau_i2c_port *port, struct i2c_msg *msg) static int i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { - struct nouveau_i2c_port *port = adap->algo_data; + struct nouveau_i2c_port *port = (struct nouveau_i2c_port *)adap; struct i2c_msg *msg = msgs; int ret = 0, mcnt = num; - if (port->func->acquire) - port->func->acquire(port); - while (!ret && mcnt--) { u8 remaining = msg->len; u8 *ptr = msg->buf; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c deleted file mode 100644 index 2ad18840fe63..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c +++ /dev/null @@ -1,143 +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 -#include - -struct nv04_i2c_priv { - struct nouveau_i2c base; -}; - -struct nv04_i2c_port { - struct nouveau_i2c_port base; - u8 drive; - u8 sense; -}; - -static void -nv04_i2c_drive_scl(struct nouveau_i2c_port *base, int state) -{ - struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv04_i2c_port *port = (void *)base; - u8 val = nv_rdvgac(priv, 0, port->drive); - if (state) val |= 0x20; - else val &= 0xdf; - nv_wrvgac(priv, 0, port->drive, val | 0x01); -} - -static void -nv04_i2c_drive_sda(struct nouveau_i2c_port *base, int state) -{ - struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv04_i2c_port *port = (void *)base; - u8 val = nv_rdvgac(priv, 0, port->drive); - if (state) val |= 0x10; - else val &= 0xef; - nv_wrvgac(priv, 0, port->drive, val | 0x01); -} - -static int -nv04_i2c_sense_scl(struct nouveau_i2c_port *base) -{ - struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv04_i2c_port *port = (void *)base; - return !!(nv_rdvgac(priv, 0, port->sense) & 0x04); -} - -static int -nv04_i2c_sense_sda(struct nouveau_i2c_port *base) -{ - struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv04_i2c_port *port = (void *)base; - return !!(nv_rdvgac(priv, 0, port->sense) & 0x08); -} - -static const struct nouveau_i2c_func -nv04_i2c_func = { - .drive_scl = nv04_i2c_drive_scl, - .drive_sda = nv04_i2c_drive_sda, - .sense_scl = nv04_i2c_sense_scl, - .sense_sda = nv04_i2c_sense_sda, -}; - -static int -nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct dcb_i2c_entry *info = data; - struct nv04_i2c_port *port; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); - *pobject = nv_object(port); - if (ret) - return ret; - - port->base.func = &nv04_i2c_func; - port->drive = info->drive; - port->sense = info->sense; - return 0; -} - -static struct nouveau_oclass -nv04_i2c_sclass[] = { - { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NV04_BIT), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_i2c_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = _nouveau_i2c_port_init, - .fini = _nouveau_i2c_port_fini, - }, - }, - {} -}; - -static int -nv04_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv04_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv04_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv04_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x04), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_i2c_ctor, - .dtor = _nouveau_i2c_dtor, - .init = _nouveau_i2c_init, - .fini = _nouveau_i2c_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c deleted file mode 100644 index f501ae25dbb3..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c +++ /dev/null @@ -1,135 +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 -#include - -struct nv4e_i2c_priv { - struct nouveau_i2c base; -}; - -struct nv4e_i2c_port { - struct nouveau_i2c_port base; - u32 addr; -}; - -static void -nv4e_i2c_drive_scl(struct nouveau_i2c_port *base, int state) -{ - struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv4e_i2c_port *port = (void *)base; - nv_mask(priv, port->addr, 0x2f, state ? 0x21 : 0x01); -} - -static void -nv4e_i2c_drive_sda(struct nouveau_i2c_port *base, int state) -{ - struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv4e_i2c_port *port = (void *)base; - nv_mask(priv, port->addr, 0x1f, state ? 0x11 : 0x01); -} - -static int -nv4e_i2c_sense_scl(struct nouveau_i2c_port *base) -{ - struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv4e_i2c_port *port = (void *)base; - return !!(nv_rd32(priv, port->addr) & 0x00040000); -} - -static int -nv4e_i2c_sense_sda(struct nouveau_i2c_port *base) -{ - struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv4e_i2c_port *port = (void *)base; - return !!(nv_rd32(priv, port->addr) & 0x00080000); -} - -static const struct nouveau_i2c_func -nv4e_i2c_func = { - .drive_scl = nv4e_i2c_drive_scl, - .drive_sda = nv4e_i2c_drive_sda, - .sense_scl = nv4e_i2c_sense_scl, - .sense_sda = nv4e_i2c_sense_sda, -}; - -static int -nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct dcb_i2c_entry *info = data; - struct nv4e_i2c_port *port; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); - *pobject = nv_object(port); - if (ret) - return ret; - - port->base.func = &nv4e_i2c_func; - port->addr = 0x600800 + info->drive; - return 0; -} - -static struct nouveau_oclass -nv4e_i2c_sclass[] = { - { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NV4E_BIT), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv4e_i2c_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = _nouveau_i2c_port_init, - .fini = _nouveau_i2c_port_fini, - }, - }, - {} -}; - -static int -nv4e_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv4e_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv4e_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv4e_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x4e), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv4e_i2c_ctor, - .dtor = _nouveau_i2c_dtor, - .init = _nouveau_i2c_init, - .fini = _nouveau_i2c_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c deleted file mode 100644 index 378dfa324e5f..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c +++ /dev/null @@ -1,149 +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" - -void -nv50_i2c_drive_scl(struct nouveau_i2c_port *base, int state) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - if (state) port->state |= 0x01; - else port->state &= 0xfe; - nv_wr32(priv, port->addr, port->state); -} - -void -nv50_i2c_drive_sda(struct nouveau_i2c_port *base, int state) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - if (state) port->state |= 0x02; - else port->state &= 0xfd; - nv_wr32(priv, port->addr, port->state); -} - -int -nv50_i2c_sense_scl(struct nouveau_i2c_port *base) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - return !!(nv_rd32(priv, port->addr) & 0x00000001); -} - -int -nv50_i2c_sense_sda(struct nouveau_i2c_port *base) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - return !!(nv_rd32(priv, port->addr) & 0x00000002); -} - -static const struct nouveau_i2c_func -nv50_i2c_func = { - .drive_scl = nv50_i2c_drive_scl, - .drive_sda = nv50_i2c_drive_sda, - .sense_scl = nv50_i2c_sense_scl, - .sense_sda = nv50_i2c_sense_sda, -}; - -const u32 nv50_i2c_addr[] = { - 0x00e138, 0x00e150, 0x00e168, 0x00e180, - 0x00e254, 0x00e274, 0x00e764, 0x00e780, - 0x00e79c, 0x00e7b8 -}; -const int nv50_i2c_addr_nr = ARRAY_SIZE(nv50_i2c_addr); - -static int -nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct dcb_i2c_entry *info = data; - struct nv50_i2c_port *port; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); - *pobject = nv_object(port); - if (ret) - return ret; - - if (info->drive >= nv50_i2c_addr_nr) - return -EINVAL; - - port->base.func = &nv50_i2c_func; - port->state = 0x00000007; - port->addr = nv50_i2c_addr[info->drive]; - return 0; -} - -int -nv50_i2c_port_init(struct nouveau_object *object) -{ - struct nv50_i2c_priv *priv = (void *)object->engine; - struct nv50_i2c_port *port = (void *)object; - nv_wr32(priv, port->addr, port->state); - return nouveau_i2c_port_init(&port->base); -} - -static struct nouveau_oclass -nv50_i2c_sclass[] = { - { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_i2c_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = nv50_i2c_port_init, - .fini = _nouveau_i2c_port_fini, - }, - }, - {} -}; - -static int -nv50_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv50_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv50_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x50), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_i2c_ctor, - .dtor = _nouveau_i2c_dtor, - .init = _nouveau_i2c_init, - .fini = _nouveau_i2c_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h deleted file mode 100644 index 4e5ba48ebf5a..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __NV50_I2C_H__ -#define __NV50_I2C_H__ - -#include - -struct nv50_i2c_priv { - struct nouveau_i2c base; -}; - -struct nv50_i2c_port { - struct nouveau_i2c_port base; - u32 addr; - u32 ctrl; - u32 data; - u32 state; -}; - -extern const u32 nv50_i2c_addr[]; -extern const int nv50_i2c_addr_nr; -int nv50_i2c_port_init(struct nouveau_object *); -int nv50_i2c_sense_scl(struct nouveau_i2c_port *); -int nv50_i2c_sense_sda(struct nouveau_i2c_port *); -void nv50_i2c_drive_scl(struct nouveau_i2c_port *, int state); -void nv50_i2c_drive_sda(struct nouveau_i2c_port *, int state); - -int nv94_aux_port_ctor(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, void *, u32, - struct nouveau_object **); -void nv94_i2c_acquire(struct nouveau_i2c_port *); -void nv94_i2c_release(struct nouveau_i2c_port *); - -#endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c deleted file mode 100644 index 61b771670bfe..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c +++ /dev/null @@ -1,285 +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" - -#define AUX_DBG(fmt, args...) nv_debug(aux, "AUXCH(%d): " fmt, ch, ##args) -#define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args) - -static void -auxch_fini(struct nouveau_i2c *aux, int ch) -{ - nv_mask(aux, 0x00e4e4 + (ch * 0x50), 0x00310000, 0x00000000); -} - -static int -auxch_init(struct nouveau_i2c *aux, int ch) -{ - const u32 unksel = 1; /* nfi which to use, or if it matters.. */ - const u32 ureq = unksel ? 0x00100000 : 0x00200000; - const u32 urep = unksel ? 0x01000000 : 0x02000000; - u32 ctrl, timeout; - - /* wait up to 1ms for any previous transaction to be done... */ - timeout = 1000; - do { - ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); - udelay(1); - if (!timeout--) { - AUX_ERR("begin idle timeout 0x%08x\n", ctrl); - return -EBUSY; - } - } while (ctrl & 0x03010000); - - /* set some magic, and wait up to 1ms for it to appear */ - nv_mask(aux, 0x00e4e4 + (ch * 0x50), 0x00300000, ureq); - timeout = 1000; - do { - ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); - udelay(1); - if (!timeout--) { - AUX_ERR("magic wait 0x%08x\n", ctrl); - auxch_fini(aux, ch); - return -EBUSY; - } - } while ((ctrl & 0x03000000) != urep); - - return 0; -} - -int -nv94_aux(struct nouveau_i2c_port *base, u8 type, u32 addr, u8 *data, u8 size) -{ - struct nouveau_i2c *aux = nouveau_i2c(base); - struct nv50_i2c_port *port = (void *)base; - u32 ctrl, stat, timeout, retries; - u32 xbuf[4] = {}; - int ch = port->addr; - int ret, i; - - AUX_DBG("%d: 0x%08x %d\n", type, addr, size); - - ret = auxch_init(aux, ch); - if (ret) - goto out; - - stat = nv_rd32(aux, 0x00e4e8 + (ch * 0x50)); - if (!(stat & 0x10000000)) { - AUX_DBG("sink not detected\n"); - ret = -ENXIO; - goto out; - } - - if (!(type & 1)) { - memcpy(xbuf, data, size); - for (i = 0; i < 16; i += 4) { - AUX_DBG("wr 0x%08x\n", xbuf[i / 4]); - nv_wr32(aux, 0x00e4c0 + (ch * 0x50) + i, xbuf[i / 4]); - } - } - - ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); - ctrl &= ~0x0001f0ff; - ctrl |= type << 12; - ctrl |= size - 1; - nv_wr32(aux, 0x00e4e0 + (ch * 0x50), addr); - - /* retry transaction a number of times on failure... */ - ret = -EREMOTEIO; - for (retries = 0; retries < 32; retries++) { - /* reset, and delay a while if this is a retry */ - nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x80000000 | ctrl); - nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x00000000 | ctrl); - if (retries) - udelay(400); - - /* transaction request, wait up to 1ms for it to complete */ - nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x00010000 | ctrl); - - timeout = 1000; - do { - ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50)); - udelay(1); - if (!timeout--) { - AUX_ERR("tx req timeout 0x%08x\n", ctrl); - goto out; - } - } while (ctrl & 0x00010000); - - /* read status, and check if transaction completed ok */ - stat = nv_mask(aux, 0x00e4e8 + (ch * 0x50), 0, 0); - if (!(stat & 0x000f0f00)) { - ret = 0; - break; - } - - AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat); - } - - if (type & 1) { - for (i = 0; i < 16; i += 4) { - xbuf[i / 4] = nv_rd32(aux, 0x00e4d0 + (ch * 0x50) + i); - AUX_DBG("rd 0x%08x\n", xbuf[i / 4]); - } - memcpy(data, xbuf, size); - } - -out: - auxch_fini(aux, ch); - return ret; -} - -void -nv94_i2c_acquire(struct nouveau_i2c_port *base) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - if (port->ctrl) { - nv_mask(priv, port->ctrl + 0x0c, 0x00000001, 0x00000000); - nv_mask(priv, port->ctrl + 0x00, 0x0000f003, port->data); - } -} - -void -nv94_i2c_release(struct nouveau_i2c_port *base) -{ -} - -static const struct nouveau_i2c_func -nv94_i2c_func = { - .acquire = nv94_i2c_acquire, - .release = nv94_i2c_release, - .drive_scl = nv50_i2c_drive_scl, - .drive_sda = nv50_i2c_drive_sda, - .sense_scl = nv50_i2c_sense_scl, - .sense_sda = nv50_i2c_sense_sda, -}; - -static int -nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct dcb_i2c_entry *info = data; - struct nv50_i2c_port *port; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); - *pobject = nv_object(port); - if (ret) - return ret; - - if (info->drive >= nv50_i2c_addr_nr) - return -EINVAL; - - port->base.func = &nv94_i2c_func; - port->state = 7; - port->addr = nv50_i2c_addr[info->drive]; - if (info->share != DCB_I2C_UNUSED) { - port->ctrl = 0x00e500 + (info->share * 0x50); - port->data = 0x0000e001; - } - return 0; -} - -static const struct nouveau_i2c_func -nv94_aux_func = { - .acquire = nv94_i2c_acquire, - .release = nv94_i2c_release, - .aux = nv94_aux, -}; - -int -nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct dcb_i2c_entry *info = data; - struct nv50_i2c_port *port; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_aux_algo, &port); - *pobject = nv_object(port); - if (ret) - return ret; - - port->base.func = &nv94_aux_func; - port->addr = info->drive; - if (info->share != DCB_I2C_UNUSED) { - port->ctrl = 0x00e500 + (info->drive * 0x50); - port->data = 0x00002002; - } - - return 0; -} - -static struct nouveau_oclass -nv94_i2c_sclass[] = { - { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv94_i2c_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = nv50_i2c_port_init, - .fini = _nouveau_i2c_port_fini, - }, - }, - { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv94_aux_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = _nouveau_i2c_port_init, - .fini = _nouveau_i2c_port_fini, - }, - }, - {} -}; - -static int -nv94_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv94_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv94_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x94), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv94_i2c_ctor, - .dtor = _nouveau_i2c_dtor, - .init = _nouveau_i2c_init, - .fini = _nouveau_i2c_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c deleted file mode 100644 index f761b8a610f1..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c +++ /dev/null @@ -1,124 +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" - -static int -nvd0_i2c_sense_scl(struct nouveau_i2c_port *base) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - return !!(nv_rd32(priv, port->addr) & 0x00000010); -} - -static int -nvd0_i2c_sense_sda(struct nouveau_i2c_port *base) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - return !!(nv_rd32(priv, port->addr) & 0x00000020); -} - -static const struct nouveau_i2c_func -nvd0_i2c_func = { - .acquire = nv94_i2c_acquire, - .release = nv94_i2c_release, - .drive_scl = nv50_i2c_drive_scl, - .drive_sda = nv50_i2c_drive_sda, - .sense_scl = nvd0_i2c_sense_scl, - .sense_sda = nvd0_i2c_sense_sda, -}; - -static int -nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 index, - struct nouveau_object **pobject) -{ - struct dcb_i2c_entry *info = data; - struct nv50_i2c_port *port; - int ret; - - ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); - *pobject = nv_object(port); - if (ret) - return ret; - - port->base.func = &nvd0_i2c_func; - port->state = 0x00000007; - port->addr = 0x00d014 + (info->drive * 0x20); - if (info->share != DCB_I2C_UNUSED) { - port->ctrl = 0x00e500 + (info->share * 0x50); - port->data = 0x0000e001; - } - return 0; -} - -static struct nouveau_oclass -nvd0_i2c_sclass[] = { - { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvd0_i2c_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = nv50_i2c_port_init, - .fini = _nouveau_i2c_port_fini, - }, - }, - { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv94_aux_port_ctor, - .dtor = _nouveau_i2c_port_dtor, - .init = _nouveau_i2c_port_init, - .fini = _nouveau_i2c_port_fini, - }, - }, - {} -}; - -static int -nvd0_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nvd0_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nvd0_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0xd0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvd0_i2c_ctor, - .dtor = _nouveau_i2c_dtor, - .init = _nouveau_i2c_init, - .fini = _nouveau_i2c_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c index 89da8fa7ea0f..23ebe477a6f0 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c @@ -37,7 +37,7 @@ nv04_mc_intr[] = { { 0x00100000, NVDEV_SUBDEV_TIMER }, { 0x01000000, NVDEV_ENGINE_DISP }, /* NV04- PCRTC0 */ { 0x02000000, NVDEV_ENGINE_DISP }, /* NV11- PCRTC1 */ - { 0x10000000, NVDEV_SUBDEV_BUS }, + { 0x10000000, NVDEV_SUBDEV_GPIO }, /* PBUS */ { 0x80000000, NVDEV_ENGINE_SW }, {} }; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c index 5965add6daee..8d759f830323 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c @@ -38,7 +38,6 @@ nv50_mc_intr[] = { { 0x00100000, NVDEV_SUBDEV_TIMER }, { 0x00200000, NVDEV_SUBDEV_GPIO }, { 0x04000000, NVDEV_ENGINE_DISP }, - { 0x10000000, NVDEV_SUBDEV_BUS }, { 0x80000000, NVDEV_ENGINE_SW }, { 0x0000d101, NVDEV_SUBDEV_FB }, {}, diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c index 3a80b29dce0f..ceb5c83f9459 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c @@ -35,12 +35,10 @@ nv98_mc_intr[] = { { 0x00001000, NVDEV_ENGINE_GR }, { 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84:NVA3 */ { 0x00008000, NVDEV_ENGINE_BSP }, - { 0x00080000, NVDEV_SUBDEV_THERM }, /* NVA3:NVC0 */ { 0x00100000, NVDEV_SUBDEV_TIMER }, { 0x00200000, NVDEV_SUBDEV_GPIO }, { 0x00400000, NVDEV_ENGINE_COPY0 }, /* NVA3- */ { 0x04000000, NVDEV_ENGINE_DISP }, - { 0x10000000, NVDEV_SUBDEV_BUS }, { 0x80000000, NVDEV_ENGINE_SW }, { 0x0040d101, NVDEV_SUBDEV_FB }, {}, diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c index 42bbf72023a8..92796682722d 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c @@ -36,13 +36,11 @@ nvc0_mc_intr[] = { { 0x00000100, NVDEV_ENGINE_FIFO }, { 0x00001000, NVDEV_ENGINE_GR }, { 0x00008000, NVDEV_ENGINE_BSP }, - { 0x00040000, NVDEV_SUBDEV_THERM }, { 0x00020000, NVDEV_ENGINE_VP }, { 0x00100000, NVDEV_SUBDEV_TIMER }, { 0x00200000, NVDEV_SUBDEV_GPIO }, { 0x02000000, NVDEV_SUBDEV_LTCG }, { 0x04000000, NVDEV_ENGINE_DISP }, - { 0x10000000, NVDEV_SUBDEV_BUS }, { 0x40000000, NVDEV_SUBDEV_IBUS }, { 0x80000000, NVDEV_ENGINE_SW }, {}, diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c index 4bde7f7f7b81..839ca1edc132 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c @@ -156,15 +156,15 @@ mxms_foreach(struct nouveau_mxm *mxm, u8 types, nv_debug(mxm, "%4s: ", mxms_desc_name[type]); for (j = headerlen - 1; j >= 0; j--) - pr_cont("%02x", dump[j]); - pr_cont("\n"); + printk("%02x", dump[j]); + printk("\n"); dump += headerlen; for (i = 0; i < entries; i++, dump += recordlen) { nv_debug(mxm, " "); for (j = recordlen - 1; j >= 0; j--) - pr_cont("%02x", dump[j]); - pr_cont("\n"); + printk("%02x", dump[j]); + printk("\n"); } } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index f794dc89a3b2..1674c74a76c8 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -29,134 +29,6 @@ #include "priv.h" -static int -nouveau_therm_update_trip(struct nouveau_therm *therm) -{ - struct nouveau_therm_priv *priv = (void *)therm; - struct nouveau_therm_trip_point *trip = priv->fan->bios.trip, - *cur_trip = NULL, - *last_trip = priv->last_trip; - u8 temp = therm->temp_get(therm); - u16 duty, i; - - /* look for the trip point corresponding to the current temperature */ - cur_trip = NULL; - for (i = 0; i < priv->fan->bios.nr_fan_trip; i++) { - if (temp >= trip[i].temp) - cur_trip = &trip[i]; - } - - /* account for the hysteresis cycle */ - if (last_trip && temp <= (last_trip->temp) && - temp > (last_trip->temp - last_trip->hysteresis)) - cur_trip = last_trip; - - if (cur_trip) { - duty = cur_trip->fan_duty; - priv->last_trip = cur_trip; - } else { - duty = 0; - priv->last_trip = NULL; - } - - return duty; -} - -static int -nouveau_therm_update_linear(struct nouveau_therm *therm) -{ - struct nouveau_therm_priv *priv = (void *)therm; - u8 linear_min_temp = priv->fan->bios.linear_min_temp; - u8 linear_max_temp = priv->fan->bios.linear_max_temp; - u8 temp = therm->temp_get(therm); - u16 duty; - - /* handle the non-linear part first */ - if (temp < linear_min_temp) - return priv->fan->bios.min_duty; - else if (temp > linear_max_temp) - return priv->fan->bios.max_duty; - - /* we are in the linear zone */ - duty = (temp - linear_min_temp); - duty *= (priv->fan->bios.max_duty - priv->fan->bios.min_duty); - duty /= (linear_max_temp - linear_min_temp); - duty += priv->fan->bios.min_duty; - - return duty; -} - -static void -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; - int duty; - - spin_lock_irqsave(&priv->lock, flags); - if (mode < 0) - mode = priv->mode; - priv->mode = mode; - - switch (mode) { - case NOUVEAU_THERM_CTRL_MANUAL: - duty = nouveau_therm_fan_get(therm); - if (duty < 0) - duty = 100; - break; - case NOUVEAU_THERM_CTRL_AUTO: - if (priv->fan->bios.nr_fan_trip) - duty = nouveau_therm_update_trip(therm); - else - duty = nouveau_therm_update_linear(therm); - break; - case NOUVEAU_THERM_CTRL_NONE: - default: - goto done; - } - - 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); - spin_unlock_irqrestore(&priv->lock, flags); -} - -static void -nouveau_therm_alarm(struct nouveau_alarm *alarm) -{ - struct nouveau_therm_priv *priv = - container_of(alarm, struct nouveau_therm_priv, alarm); - nouveau_therm_update(&priv->base, -1); -} - -int -nouveau_therm_mode(struct nouveau_therm *therm, int mode) -{ - struct nouveau_therm_priv *priv = (void *)therm; - struct nouveau_device *device = nv_device(therm); - static const char *name[] = { - "disabled", - "manual", - "automatic" - }; - - /* The default PDAEMON ucode interferes with fan management */ - if ((mode >= ARRAY_SIZE(name)) || - (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0)) - return -EINVAL; - - if (priv->mode == mode) - return 0; - - nv_info(therm, "Thermal management: %s\n", name[mode]); - nouveau_therm_update(therm, mode); - return 0; -} - int nouveau_therm_attr_get(struct nouveau_therm *therm, enum nouveau_therm_attr_type type) @@ -165,11 +37,11 @@ nouveau_therm_attr_get(struct nouveau_therm *therm, switch (type) { case NOUVEAU_THERM_ATTR_FAN_MIN_DUTY: - return priv->fan->bios.min_duty; + return priv->bios_fan.min_duty; case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY: - return priv->fan->bios.max_duty; + return priv->bios_fan.max_duty; case NOUVEAU_THERM_ATTR_FAN_MODE: - return priv->mode; + return priv->fan.mode; case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: return priv->bios_sensor.thrs_fan_boost.temp; case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST: @@ -201,50 +73,42 @@ nouveau_therm_attr_set(struct nouveau_therm *therm, case NOUVEAU_THERM_ATTR_FAN_MIN_DUTY: if (value < 0) value = 0; - if (value > priv->fan->bios.max_duty) - value = priv->fan->bios.max_duty; - priv->fan->bios.min_duty = value; + if (value > priv->bios_fan.max_duty) + value = priv->bios_fan.max_duty; + priv->bios_fan.min_duty = value; return 0; case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY: if (value < 0) value = 0; - if (value < priv->fan->bios.min_duty) - value = priv->fan->bios.min_duty; - priv->fan->bios.max_duty = value; + if (value < priv->bios_fan.min_duty) + value = priv->bios_fan.min_duty; + priv->bios_fan.max_duty = value; return 0; case NOUVEAU_THERM_ATTR_FAN_MODE: - return nouveau_therm_mode(therm, value); + return nouveau_therm_fan_set_mode(therm, value); case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: priv->bios_sensor.thrs_fan_boost.temp = value; - priv->sensor.program_alarms(therm); return 0; case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST: priv->bios_sensor.thrs_fan_boost.hysteresis = value; - priv->sensor.program_alarms(therm); return 0; case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK: priv->bios_sensor.thrs_down_clock.temp = value; - priv->sensor.program_alarms(therm); return 0; case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST: priv->bios_sensor.thrs_down_clock.hysteresis = value; - priv->sensor.program_alarms(therm); return 0; case NOUVEAU_THERM_ATTR_THRS_CRITICAL: priv->bios_sensor.thrs_critical.temp = value; - priv->sensor.program_alarms(therm); return 0; case NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST: priv->bios_sensor.thrs_critical.hysteresis = value; - priv->sensor.program_alarms(therm); return 0; case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN: priv->bios_sensor.thrs_shutdown.temp = value; - priv->sensor.program_alarms(therm); return 0; case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST: priv->bios_sensor.thrs_shutdown.hysteresis = value; - priv->sensor.program_alarms(therm); return 0; } @@ -252,7 +116,7 @@ nouveau_therm_attr_set(struct nouveau_therm *therm, } int -_nouveau_therm_init(struct nouveau_object *object) +nouveau_therm_init(struct nouveau_object *object) { struct nouveau_therm *therm = (void *)object; struct nouveau_therm_priv *priv = (void *)therm; @@ -262,69 +126,19 @@ _nouveau_therm_init(struct nouveau_object *object) if (ret) return ret; - if (priv->suspend >= 0) - nouveau_therm_mode(therm, priv->mode); - priv->sensor.program_alarms(therm); + if (priv->fan.percent >= 0) + therm->fan_set(therm, priv->fan.percent); + return 0; } int -_nouveau_therm_fini(struct nouveau_object *object, bool suspend) +nouveau_therm_fini(struct nouveau_object *object, bool suspend) { struct nouveau_therm *therm = (void *)object; struct nouveau_therm_priv *priv = (void *)therm; - if (suspend) { - priv->suspend = priv->mode; - priv->mode = NOUVEAU_THERM_CTRL_NONE; - } + priv->fan.percent = therm->fan_get(therm); return nouveau_subdev_fini(&therm->base, suspend); } - -int -nouveau_therm_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, - int length, void **pobject) -{ - struct nouveau_therm_priv *priv; - int ret; - - ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PTHERM", - "therm", length, pobject); - priv = *pobject; - if (ret) - return ret; - - nouveau_alarm_init(&priv->alarm, nouveau_therm_alarm); - spin_lock_init(&priv->lock); - spin_lock_init(&priv->sensor.alarm_program_lock); - - priv->base.fan_get = nouveau_therm_fan_user_get; - priv->base.fan_set = nouveau_therm_fan_user_set; - priv->base.fan_sense = nouveau_therm_fan_sense; - priv->base.attr_get = nouveau_therm_attr_get; - priv->base.attr_set = nouveau_therm_attr_set; - priv->mode = priv->suspend = -1; /* undefined */ - return 0; -} - -int -nouveau_therm_preinit(struct nouveau_therm *therm) -{ - nouveau_therm_ic_ctor(therm); - nouveau_therm_sensor_ctor(therm); - nouveau_therm_fan_ctor(therm); - - nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_NONE); - return 0; -} - -void -_nouveau_therm_dtor(struct nouveau_object *object) -{ - struct nouveau_therm_priv *priv = (void *)object; - kfree(priv->fan); - nouveau_subdev_destroy(&priv->base.base); -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c index c728380d3d62..523178685180 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c @@ -27,107 +27,90 @@ #include #include - #include #include -static int -nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target) +int +nouveau_therm_fan_get(struct nouveau_therm *therm) { - struct nouveau_therm *therm = fan->parent; struct nouveau_therm_priv *priv = (void *)therm; - struct nouveau_timer *ptimer = nouveau_timer(priv); - unsigned long flags; - int ret = 0; - int duty; - - /* update target fan speed, restricting to allowed range */ - spin_lock_irqsave(&fan->lock, flags); - if (target < 0) - target = fan->percent; - target = max_t(u8, target, fan->bios.min_duty); - target = min_t(u8, target, fan->bios.max_duty); - if (fan->percent != target) { - nv_debug(therm, "FAN target: %d\n", target); - fan->percent = target; - } + struct nouveau_gpio *gpio = nouveau_gpio(therm); + struct dcb_gpio_func func; + int card_type = nv_device(therm)->card_type; + u32 divs, duty; + int ret; - /* check that we're not already at the target duty cycle */ - duty = fan->get(therm); - if (duty == target) - goto done; - - /* smooth out the fanspeed increase/decrease */ - if (!immediate && duty >= 0) { - /* the constant "3" is a rough approximation taken from - * nvidia's behaviour. - * it is meant to bump the fan speed more incrementally - */ - if (duty < target) - duty = min(duty + 3, target); - else if (duty > target) - duty = max(duty - 3, target); - } else { - duty = target; - } + if (!priv->fan.pwm_get) + return -ENODEV; - nv_debug(therm, "FAN update: %d\n", duty); - ret = fan->set(therm, duty); - if (ret) - goto done; - - /* schedule next fan update, if not at target speed already */ - if (list_empty(&fan->alarm.head) && target != duty) { - u16 bump_period = fan->bios.bump_period; - u16 slow_down_period = fan->bios.slow_down_period; - u64 delay; - - if (duty > target) - delay = slow_down_period; - else if (duty == target) - delay = min(bump_period, slow_down_period) ; - else - delay = bump_period; - - ptimer->alarm(ptimer, delay * 1000 * 1000, &fan->alarm); + ret = gpio->find(gpio, 0, DCB_GPIO_PWM_FAN, 0xff, &func); + if (ret == 0) { + ret = priv->fan.pwm_get(therm, func.line, &divs, &duty); + if (ret == 0 && divs) { + divs = max(divs, duty); + if (card_type <= NV_40 || (func.log[0] & 1)) + duty = divs - duty; + return (duty * 100) / divs; + } + + return gpio->get(gpio, 0, func.func, func.line) * 100; } -done: - spin_unlock_irqrestore(&fan->lock, flags); - return ret; -} - -static void -nouveau_fan_alarm(struct nouveau_alarm *alarm) -{ - struct nouveau_fan *fan = container_of(alarm, struct nouveau_fan, alarm); - nouveau_fan_update(fan, false, -1); + return -ENODEV; } int -nouveau_therm_fan_get(struct nouveau_therm *therm) +nouveau_therm_fan_set(struct nouveau_therm *therm, int percent) { struct nouveau_therm_priv *priv = (void *)therm; - return priv->fan->get(therm); -} + struct nouveau_gpio *gpio = nouveau_gpio(therm); + struct dcb_gpio_func func; + int card_type = nv_device(therm)->card_type; + u32 divs, duty; + int ret; -int -nouveau_therm_fan_set(struct nouveau_therm *therm, bool immediate, int percent) -{ - struct nouveau_therm_priv *priv = (void *)therm; - return nouveau_fan_update(priv->fan, immediate, percent); + if (priv->fan.mode == FAN_CONTROL_NONE) + return -EINVAL; + + if (!priv->fan.pwm_set) + return -ENODEV; + + if (percent < priv->bios_fan.min_duty) + percent = priv->bios_fan.min_duty; + if (percent > priv->bios_fan.max_duty) + percent = priv->bios_fan.max_duty; + + ret = gpio->find(gpio, 0, DCB_GPIO_PWM_FAN, 0xff, &func); + if (ret == 0) { + divs = priv->bios_perf_fan.pwm_divisor; + if (priv->bios_fan.pwm_freq) { + divs = 1; + if (priv->fan.pwm_clock) + divs = priv->fan.pwm_clock(therm); + divs /= priv->bios_fan.pwm_freq; + } + + duty = ((divs * percent) + 99) / 100; + if (card_type <= NV_40 || (func.log[0] & 1)) + duty = divs - duty; + + ret = priv->fan.pwm_set(therm, func.line, divs, duty); + return ret; + } + + return -ENODEV; } int nouveau_therm_fan_sense(struct nouveau_therm *therm) { - struct nouveau_therm_priv *priv = (void *)therm; struct nouveau_timer *ptimer = nouveau_timer(therm); struct nouveau_gpio *gpio = nouveau_gpio(therm); + struct dcb_gpio_func func; u32 cycles, cur, prev; u64 start, end, tach; - if (priv->fan->tach.func == DCB_GPIO_UNUSED) + if (gpio->find(gpio, 0, DCB_GPIO_FAN_SENSE, 0xff, &func)) return -ENODEV; /* Time a complete rotation and extrapolate to RPM: @@ -135,12 +118,12 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm) * We get 4 changes (0 -> 1 -> 0 -> 1) per complete rotation. */ start = ptimer->read(ptimer); - prev = gpio->get(gpio, 0, priv->fan->tach.func, priv->fan->tach.line); + prev = gpio->get(gpio, 0, func.func, func.line); cycles = 0; do { usleep_range(500, 1000); /* supports 0 < rpm < 7500 */ - cur = gpio->get(gpio, 0, priv->fan->tach.func, priv->fan->tach.line); + cur = gpio->get(gpio, 0, func.func, func.line); if (prev != cur) { if (!start) start = ptimer->read(ptimer); @@ -158,6 +141,34 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm) return 0; } +int +nouveau_therm_fan_set_mode(struct nouveau_therm *therm, + enum nouveau_therm_fan_mode mode) +{ + struct nouveau_therm_priv *priv = (void *)therm; + + if (priv->fan.mode == mode) + return 0; + + if (mode < FAN_CONTROL_NONE || mode >= FAN_CONTROL_NR) + return -EINVAL; + + switch (mode) + { + case FAN_CONTROL_NONE: + nv_info(therm, "switch fan to no-control mode\n"); + break; + case FAN_CONTROL_MANUAL: + nv_info(therm, "switch fan to manual mode\n"); + break; + case FAN_CONTROL_NR: + break; + } + + priv->fan.mode = mode; + return 0; +} + int nouveau_therm_fan_user_get(struct nouveau_therm *therm) { @@ -169,86 +180,55 @@ nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent) { struct nouveau_therm_priv *priv = (void *)therm; - if (priv->mode != NOUVEAU_THERM_CTRL_MANUAL) + if (priv->fan.mode != FAN_CONTROL_MANUAL) return -EINVAL; - return nouveau_therm_fan_set(therm, true, percent); + return nouveau_therm_fan_set(therm, percent); } -static void +void nouveau_therm_fan_set_defaults(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; - priv->fan->bios.pwm_freq = 0; - priv->fan->bios.min_duty = 0; - priv->fan->bios.max_duty = 100; - priv->fan->bios.bump_period = 500; - priv->fan->bios.slow_down_period = 2000; - priv->fan->bios.linear_min_temp = 40; - priv->fan->bios.linear_max_temp = 85; + priv->bios_fan.pwm_freq = 0; + priv->bios_fan.min_duty = 0; + priv->bios_fan.max_duty = 100; } + static void nouveau_therm_fan_safety_checks(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; - if (priv->fan->bios.min_duty > 100) - priv->fan->bios.min_duty = 100; - if (priv->fan->bios.max_duty > 100) - priv->fan->bios.max_duty = 100; + if (priv->bios_fan.min_duty > 100) + priv->bios_fan.min_duty = 100; + if (priv->bios_fan.max_duty > 100) + priv->bios_fan.max_duty = 100; - if (priv->fan->bios.min_duty > priv->fan->bios.max_duty) - priv->fan->bios.min_duty = priv->fan->bios.max_duty; + if (priv->bios_fan.min_duty > priv->bios_fan.max_duty) + priv->bios_fan.min_duty = priv->bios_fan.max_duty; +} + +int nouveau_fan_pwm_clock_dummy(struct nouveau_therm *therm) +{ + return 1; } int nouveau_therm_fan_ctor(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; - struct nouveau_gpio *gpio = nouveau_gpio(therm); struct nouveau_bios *bios = nouveau_bios(therm); - struct dcb_gpio_func func; - int ret; - /* attempt to locate a drivable fan, and determine control method */ - ret = gpio->find(gpio, 0, DCB_GPIO_FAN, 0xff, &func); - if (ret == 0) { - if (func.log[0] & DCB_GPIO_LOG_DIR_IN) { - nv_debug(therm, "GPIO_FAN is in input mode\n"); - ret = -EINVAL; - } else { - ret = nouveau_fanpwm_create(therm, &func); - if (ret != 0) - ret = nouveau_fantog_create(therm, &func); - } - } - - /* no controllable fan found, create a dummy fan module */ - if (ret != 0) { - ret = nouveau_fannil_create(therm); - if (ret) - return ret; - } - - nv_info(therm, "FAN control: %s\n", priv->fan->type); - - /* attempt to detect a tachometer connection */ - ret = gpio->find(gpio, 0, DCB_GPIO_FAN_SENSE, 0xff, &priv->fan->tach); - if (ret) - priv->fan->tach.func = DCB_GPIO_UNUSED; - - /* initialise fan bump/slow update handling */ - priv->fan->parent = therm; - nouveau_alarm_init(&priv->fan->alarm, nouveau_fan_alarm); - spin_lock_init(&priv->fan->lock); - - /* other random init... */ nouveau_therm_fan_set_defaults(therm); - nvbios_perf_fan_parse(bios, &priv->fan->perf); - if (nvbios_therm_fan_parse(bios, &priv->fan->bios)) + nvbios_perf_fan_parse(bios, &priv->bios_perf_fan); + if (nvbios_therm_fan_parse(bios, &priv->bios_fan)) nv_error(therm, "parsing the thermal table failed\n"); nouveau_therm_fan_safety_checks(therm); + + nouveau_therm_fan_set_mode(therm, FAN_CONTROL_NONE); + return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fannil.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fannil.c deleted file mode 100644 index b78c182e1d51..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fannil.c +++ /dev/null @@ -1,54 +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 "priv.h" - -static int -nouveau_fannil_get(struct nouveau_therm *therm) -{ - return -ENODEV; -} - -static int -nouveau_fannil_set(struct nouveau_therm *therm, int percent) -{ - return -ENODEV; -} - -int -nouveau_fannil_create(struct nouveau_therm *therm) -{ - struct nouveau_therm_priv *tpriv = (void *)therm; - struct nouveau_fan *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - tpriv->fan = priv; - if (!priv) - return -ENOMEM; - - priv->type = "none / external"; - priv->get = nouveau_fannil_get; - priv->set = nouveau_fannil_set; - return 0; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c deleted file mode 100644 index 5f71db8e8992..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c +++ /dev/null @@ -1,107 +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 - * Martin Peres - */ - -#include -#include - -#include "priv.h" - -struct nouveau_fanpwm_priv { - struct nouveau_fan base; - struct dcb_gpio_func func; -}; - -static int -nouveau_fanpwm_get(struct nouveau_therm *therm) -{ - struct nouveau_therm_priv *tpriv = (void *)therm; - struct nouveau_fanpwm_priv *priv = (void *)tpriv->fan; - struct nouveau_gpio *gpio = nouveau_gpio(therm); - int card_type = nv_device(therm)->card_type; - u32 divs, duty; - int ret; - - ret = therm->pwm_get(therm, priv->func.line, &divs, &duty); - if (ret == 0 && divs) { - divs = max(divs, duty); - if (card_type <= NV_40 || (priv->func.log[0] & 1)) - duty = divs - duty; - return (duty * 100) / divs; - } - - return gpio->get(gpio, 0, priv->func.func, priv->func.line) * 100; -} - -static int -nouveau_fanpwm_set(struct nouveau_therm *therm, int percent) -{ - struct nouveau_therm_priv *tpriv = (void *)therm; - struct nouveau_fanpwm_priv *priv = (void *)tpriv->fan; - int card_type = nv_device(therm)->card_type; - u32 divs, duty; - int ret; - - divs = priv->base.perf.pwm_divisor; - if (priv->base.bios.pwm_freq) { - divs = 1; - if (therm->pwm_clock) - divs = therm->pwm_clock(therm); - divs /= priv->base.bios.pwm_freq; - } - - duty = ((divs * percent) + 99) / 100; - if (card_type <= NV_40 || (priv->func.log[0] & 1)) - duty = divs - duty; - - ret = therm->pwm_set(therm, priv->func.line, divs, duty); - if (ret == 0) - ret = therm->pwm_ctrl(therm, priv->func.line, true); - return ret; -} - -int -nouveau_fanpwm_create(struct nouveau_therm *therm, struct dcb_gpio_func *func) -{ - struct nouveau_device *device = nv_device(therm); - struct nouveau_therm_priv *tpriv = (void *)therm; - struct nouveau_fanpwm_priv *priv; - u32 divs, duty; - - if (!nouveau_boolopt(device->cfgopt, "NvFanPWM", func->param) || - !therm->pwm_ctrl || - therm->pwm_get(therm, func->line, &divs, &duty) == -ENODEV) - return -ENODEV; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - tpriv->fan = &priv->base; - if (!priv) - return -ENOMEM; - - priv->base.type = "PWM"; - priv->base.get = nouveau_fanpwm_get; - priv->base.set = nouveau_fanpwm_set; - priv->func = *func; - return 0; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c deleted file mode 100644 index e601773ee475..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2012 The 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 "priv.h" - -#include -#include - -#include -#include - -struct nouveau_fantog_priv { - struct nouveau_fan base; - struct nouveau_alarm alarm; - spinlock_t lock; - u32 period_us; - u32 percent; - struct dcb_gpio_func func; -}; - -static void -nouveau_fantog_update(struct nouveau_fantog_priv *priv, int percent) -{ - struct nouveau_therm_priv *tpriv = (void *)priv->base.parent; - struct nouveau_timer *ptimer = nouveau_timer(tpriv); - struct nouveau_gpio *gpio = nouveau_gpio(tpriv); - unsigned long flags; - int duty; - - spin_lock_irqsave(&priv->lock, flags); - if (percent < 0) - percent = priv->percent; - priv->percent = percent; - - duty = !gpio->get(gpio, 0, DCB_GPIO_FAN, 0xff); - gpio->set(gpio, 0, DCB_GPIO_FAN, 0xff, duty); - - if (list_empty(&priv->alarm.head) && percent != (duty * 100)) { - u64 next_change = (percent * priv->period_us) / 100; - if (!duty) - next_change = priv->period_us - next_change; - ptimer->alarm(ptimer, next_change * 1000, &priv->alarm); - } - spin_unlock_irqrestore(&priv->lock, flags); -} - -static void -nouveau_fantog_alarm(struct nouveau_alarm *alarm) -{ - struct nouveau_fantog_priv *priv = - container_of(alarm, struct nouveau_fantog_priv, alarm); - nouveau_fantog_update(priv, -1); -} - -static int -nouveau_fantog_get(struct nouveau_therm *therm) -{ - struct nouveau_therm_priv *tpriv = (void *)therm; - struct nouveau_fantog_priv *priv = (void *)tpriv->fan; - return priv->percent; -} - -static int -nouveau_fantog_set(struct nouveau_therm *therm, int percent) -{ - struct nouveau_therm_priv *tpriv = (void *)therm; - struct nouveau_fantog_priv *priv = (void *)tpriv->fan; - if (therm->pwm_ctrl) - therm->pwm_ctrl(therm, priv->func.line, false); - nouveau_fantog_update(priv, percent); - return 0; -} - -int -nouveau_fantog_create(struct nouveau_therm *therm, struct dcb_gpio_func *func) -{ - struct nouveau_therm_priv *tpriv = (void *)therm; - struct nouveau_fantog_priv *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - tpriv->fan = &priv->base; - if (!priv) - return -ENOMEM; - - priv->base.type = "toggle"; - priv->base.get = nouveau_fantog_get; - priv->base.set = nouveau_fantog_set; - nouveau_alarm_init(&priv->alarm, nouveau_fantog_alarm); - priv->period_us = 100000; /* 10Hz */ - priv->percent = 100; - priv->func = *func; - spin_lock_init(&priv->lock); - return 0; -} diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c index e24090bac195..e512ff0aae60 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c @@ -31,7 +31,7 @@ static bool probe_monitoring_device(struct nouveau_i2c_port *i2c, struct i2c_board_info *info) { - struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c); + struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c->i2c); struct i2c_client *client; request_module("%s%s", I2C_MODULE_PREFIX, info->type); @@ -53,31 +53,6 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c, return true; } -static struct i2c_board_info -nv_board_infos[] = { - { 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) }, - { } -}; - void nouveau_therm_ic_ctor(struct nouveau_therm *therm) { @@ -85,6 +60,29 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm) struct nouveau_bios *bios = nouveau_bios(therm); struct nouveau_i2c *i2c = nouveau_i2c(therm); struct nvbios_extdev_func extdev_entry; + struct i2c_board_info info[] = { + { 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) }, + { } + }; if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_LM89, &extdev_entry)) { struct i2c_board_info board[] = { @@ -113,6 +111,6 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm) /* The vbios doesn't provide the address of an exisiting monitoring device. Let's try our static list. */ - i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", - nv_board_infos, probe_monitoring_device); + i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", info, + probe_monitoring_device); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index 0f5363edb964..fcf2cfe731d6 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -25,10 +25,6 @@ #include "priv.h" -struct nv40_therm_priv { - struct nouveau_therm_priv base; -}; - static int nv40_sensor_setup(struct nouveau_therm *therm) { @@ -38,7 +34,6 @@ nv40_sensor_setup(struct nouveau_therm *therm) if (device->chipset >= 0x46) { nv_mask(therm, 0x15b8, 0x80000000, 0); nv_wr32(therm, 0x15b0, 0x80003fff); - mdelay(10); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0x3fff; } else { nv_wr32(therm, 0x15b0, 0xff); @@ -80,20 +75,7 @@ nv40_temp_get(struct nouveau_therm *therm) return core_temp; } -static int -nv40_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable) -{ - u32 mask = enable ? 0x80000000 : 0x0000000; - if (line == 2) nv_mask(therm, 0x0010f0, 0x80000000, mask); - else if (line == 9) nv_mask(therm, 0x0015f4, 0x80000000, mask); - else { - nv_error(therm, "unknown pwm ctrl for gpio %d\n", line); - return -ENODEV; - } - return 0; -} - -static int +int nv40_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty) { if (line == 2) { @@ -119,15 +101,15 @@ nv40_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty) return -EINVAL; } -static int +int nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty) { if (line == 2) { - nv_mask(therm, 0x0010f0, 0x7fff7fff, (duty << 16) | divs); + nv_wr32(therm, 0x0010f0, 0x80000000 | (duty << 16) | divs); } else if (line == 9) { nv_wr32(therm, 0x0015f8, divs); - nv_mask(therm, 0x0015f4, 0x7fffffff, duty); + nv_wr32(therm, 0x0015f4, duty | 0x80000000); } else { nv_error(therm, "unknown pwm ctrl for gpio %d\n", line); return -ENODEV; @@ -136,51 +118,37 @@ nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty) return 0; } -static void -nv40_therm_intr(struct nouveau_subdev *subdev) -{ - struct nouveau_therm *therm = nouveau_therm(subdev); - uint32_t stat = nv_rd32(therm, 0x1100); - - /* traitement */ - - /* ack all IRQs */ - nv_wr32(therm, 0x1100, 0x70000); - - nv_error(therm, "THERM received an IRQ: stat = %x\n", stat); -} - static int nv40_therm_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { - struct nv40_therm_priv *priv; + struct nouveau_therm_priv *priv; + struct nouveau_therm *therm; int ret; ret = nouveau_therm_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); + therm = (void *) priv; if (ret) return ret; - priv->base.base.pwm_ctrl = nv40_fan_pwm_ctrl; - priv->base.base.pwm_get = nv40_fan_pwm_get; - priv->base.base.pwm_set = nv40_fan_pwm_set; - priv->base.base.temp_get = nv40_temp_get; - priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling; - nv_subdev(priv)->intr = nv40_therm_intr; - return nouveau_therm_preinit(&priv->base.base); -} + nouveau_therm_ic_ctor(therm); + nouveau_therm_sensor_ctor(therm); + nouveau_therm_fan_ctor(therm); -static int -nv40_therm_init(struct nouveau_object *object) -{ - struct nouveau_therm *therm = (void *)object; + priv->fan.pwm_get = nv40_fan_pwm_get; + priv->fan.pwm_set = nv40_fan_pwm_set; - nv40_sensor_setup(therm); + therm->temp_get = nv40_temp_get; + therm->fan_get = nouveau_therm_fan_user_get; + therm->fan_set = nouveau_therm_fan_user_set; + therm->fan_sense = nouveau_therm_fan_sense; + therm->attr_get = nouveau_therm_attr_get; + therm->attr_set = nouveau_therm_attr_set; - return _nouveau_therm_init(object); + return 0; } struct nouveau_oclass @@ -189,7 +157,7 @@ nv40_therm_oclass = { .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv40_therm_ctor, .dtor = _nouveau_therm_dtor, - .init = nv40_therm_init, - .fini = _nouveau_therm_fini, + .init = nouveau_therm_init, + .fini = nouveau_therm_fini, }, -}; +}; \ No newline at end of file diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c index 86632cbd65ce..9360ddd469e7 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c @@ -25,10 +25,6 @@ #include "priv.h" -struct nv50_therm_priv { - struct nouveau_therm_priv base; -}; - static int pwm_info(struct nouveau_therm *therm, int *line, int *ctrl, int *indx) { @@ -54,16 +50,6 @@ pwm_info(struct nouveau_therm *therm, int *line, int *ctrl, int *indx) return 0; } -int -nv50_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable) -{ - u32 data = enable ? 0x00000001 : 0x00000000; - int ctrl, id, ret = pwm_info(therm, &line, &ctrl, &id); - if (ret == 0) - nv_mask(therm, ctrl, 0x00010001 << line, data << line); - return ret; -} - int nv50_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty) { @@ -87,6 +73,7 @@ nv50_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty) if (ret) return ret; + nv_mask(therm, ctrl, 0x00010001 << line, 0x00000001 << line); nv_wr32(therm, 0x00e114 + (id * 8), divs); nv_wr32(therm, 0x00e118 + (id * 8), duty | 0x80000000); return 0; @@ -124,178 +111,38 @@ nv50_temp_get(struct nouveau_therm *therm) return nv_rd32(therm, 0x20400); } -static void -nv50_therm_program_alarms(struct nouveau_therm *therm) -{ - struct nouveau_therm_priv *priv = (void *)therm; - struct nvbios_therm_sensor *sensor = &priv->bios_sensor; - unsigned long flags; - - spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags); - - /* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */ - nv_wr32(therm, 0x20000, 0x000003ff); - - /* shutdown: The computer should be shutdown when reached */ - nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis); - nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp); - - /* THRS_1 : fan boost*/ - nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp); - - /* THRS_2 : critical */ - nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp); - - /* THRS_4 : down clock */ - nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp); - spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); - - nv_info(therm, - "Programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n", - sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis, - sensor->thrs_down_clock.temp, - sensor->thrs_down_clock.hysteresis, - sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis, - sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis); - -} - -/* must be called with alarm_program_lock taken ! */ -static void -nv50_therm_threshold_hyst_emulation(struct nouveau_therm *therm, - uint32_t thrs_reg, u8 status_bit, - const struct nvbios_therm_threshold *thrs, - enum nouveau_therm_thrs thrs_name) -{ - enum nouveau_therm_thrs_direction direction; - enum nouveau_therm_thrs_state prev_state, new_state; - int temp, cur; - - prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name); - temp = nv_rd32(therm, thrs_reg); - - /* program the next threshold */ - if (temp == thrs->temp) { - nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis); - new_state = NOUVEAU_THERM_THRS_HIGHER; - } else { - nv_wr32(therm, thrs_reg, thrs->temp); - new_state = NOUVEAU_THERM_THRS_LOWER; - } - - /* fix the state (in case someone reprogrammed the alarms) */ - cur = therm->temp_get(therm); - if (new_state == NOUVEAU_THERM_THRS_LOWER && cur > thrs->temp) - new_state = NOUVEAU_THERM_THRS_HIGHER; - else if (new_state == NOUVEAU_THERM_THRS_HIGHER && - cur < thrs->temp - thrs->hysteresis) - new_state = NOUVEAU_THERM_THRS_LOWER; - nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state); - - /* find the direction */ - if (prev_state < new_state) - direction = NOUVEAU_THERM_THRS_RISING; - else if (prev_state > new_state) - direction = NOUVEAU_THERM_THRS_FALLING; - else - return; - - /* advertise a change in direction */ - nouveau_therm_sensor_event(therm, thrs_name, direction); -} - -static void -nv50_therm_intr(struct nouveau_subdev *subdev) -{ - struct nouveau_therm *therm = nouveau_therm(subdev); - struct nouveau_therm_priv *priv = (void *)therm; - struct nvbios_therm_sensor *sensor = &priv->bios_sensor; - unsigned long flags; - uint32_t intr; - - spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags); - - intr = nv_rd32(therm, 0x20100); - - /* THRS_4: downclock */ - if (intr & 0x002) { - nv50_therm_threshold_hyst_emulation(therm, 0x20414, 24, - &sensor->thrs_down_clock, - NOUVEAU_THERM_THRS_DOWNCLOCK); - intr &= ~0x002; - } - - /* shutdown */ - if (intr & 0x004) { - nv50_therm_threshold_hyst_emulation(therm, 0x20480, 20, - &sensor->thrs_shutdown, - NOUVEAU_THERM_THRS_SHUTDOWN); - intr &= ~0x004; - } - - /* THRS_1 : fan boost */ - if (intr & 0x008) { - nv50_therm_threshold_hyst_emulation(therm, 0x204c4, 21, - &sensor->thrs_fan_boost, - NOUVEAU_THERM_THRS_FANBOOST); - intr &= ~0x008; - } - - /* THRS_2 : critical */ - if (intr & 0x010) { - nv50_therm_threshold_hyst_emulation(therm, 0x204c0, 22, - &sensor->thrs_critical, - NOUVEAU_THERM_THRS_CRITICAL); - intr &= ~0x010; - } - - if (intr) - nv_error(therm, "unhandled intr 0x%08x\n", intr); - - /* ACK everything */ - nv_wr32(therm, 0x20100, 0xffffffff); - nv_wr32(therm, 0x1100, 0x10000); /* PBUS */ - - spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); -} - static int nv50_therm_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { - struct nv50_therm_priv *priv; + struct nouveau_therm_priv *priv; + struct nouveau_therm *therm; int ret; ret = nouveau_therm_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); + therm = (void *) priv; if (ret) return ret; - priv->base.base.pwm_ctrl = nv50_fan_pwm_ctrl; - priv->base.base.pwm_get = nv50_fan_pwm_get; - priv->base.base.pwm_set = nv50_fan_pwm_set; - priv->base.base.pwm_clock = nv50_fan_pwm_clock; - priv->base.base.temp_get = nv50_temp_get; - priv->base.sensor.program_alarms = nv50_therm_program_alarms; - nv_subdev(priv)->intr = nv50_therm_intr; + nouveau_therm_ic_ctor(therm); + nouveau_therm_sensor_ctor(therm); + nouveau_therm_fan_ctor(therm); - /* init the thresholds */ - nouveau_therm_sensor_set_threshold_state(&priv->base.base, - NOUVEAU_THERM_THRS_SHUTDOWN, - NOUVEAU_THERM_THRS_LOWER); - nouveau_therm_sensor_set_threshold_state(&priv->base.base, - NOUVEAU_THERM_THRS_FANBOOST, - NOUVEAU_THERM_THRS_LOWER); - nouveau_therm_sensor_set_threshold_state(&priv->base.base, - NOUVEAU_THERM_THRS_CRITICAL, - NOUVEAU_THERM_THRS_LOWER); - nouveau_therm_sensor_set_threshold_state(&priv->base.base, - NOUVEAU_THERM_THRS_DOWNCLOCK, - NOUVEAU_THERM_THRS_LOWER); + priv->fan.pwm_get = nv50_fan_pwm_get; + priv->fan.pwm_set = nv50_fan_pwm_set; + priv->fan.pwm_clock = nv50_fan_pwm_clock; - return nouveau_therm_preinit(&priv->base.base); + therm->temp_get = nv50_temp_get; + therm->fan_get = nouveau_therm_fan_user_get; + therm->fan_set = nouveau_therm_fan_user_set; + therm->fan_sense = nouveau_therm_fan_sense; + therm->attr_get = nouveau_therm_attr_get; + therm->attr_set = nouveau_therm_attr_set; + + return 0; } struct nouveau_oclass @@ -304,7 +151,7 @@ nv50_therm_oclass = { .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_therm_ctor, .dtor = _nouveau_therm_dtor, - .init = _nouveau_therm_init, - .fini = _nouveau_therm_fini, + .init = nouveau_therm_init, + .fini = nouveau_therm_fini, }, }; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c deleted file mode 100644 index 2dcc5437116a..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c +++ /dev/null @@ -1,99 +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 - -#include "priv.h" - -struct nva3_therm_priv { - struct nouveau_therm_priv base; -}; - -int -nva3_therm_fan_sense(struct nouveau_therm *therm) -{ - u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff; - u32 ctrl = nv_rd32(therm, 0x00e720); - if (ctrl & 0x00000001) - return tach * 60; - return -ENODEV; -} - -static int -nva3_therm_init(struct nouveau_object *object) -{ - struct nva3_therm_priv *priv = (void *)object; - struct dcb_gpio_func *tach = &priv->base.fan->tach; - int ret; - - ret = nouveau_therm_init(&priv->base.base); - if (ret) - return ret; - - /* enable fan tach, count revolutions per-second */ - nv_mask(priv, 0x00e720, 0x00000003, 0x00000002); - if (tach->func != DCB_GPIO_UNUSED) { - nv_wr32(priv, 0x00e724, nv_device(priv)->crystal * 1000); - nv_mask(priv, 0x00e720, 0x001f0000, tach->line << 16); - nv_mask(priv, 0x00e720, 0x00000001, 0x00000001); - } - nv_mask(priv, 0x00e720, 0x00000002, 0x00000000); - - return 0; -} - -static int -nva3_therm_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nva3_therm_priv *priv; - int ret; - - ret = nouveau_therm_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.base.pwm_ctrl = nv50_fan_pwm_ctrl; - priv->base.base.pwm_get = nv50_fan_pwm_get; - priv->base.base.pwm_set = nv50_fan_pwm_set; - priv->base.base.pwm_clock = nv50_fan_pwm_clock; - priv->base.base.temp_get = nv50_temp_get; - priv->base.base.fan_sense = nva3_therm_fan_sense; - priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling; - return nouveau_therm_preinit(&priv->base.base); -} - -struct nouveau_oclass -nva3_therm_oclass = { - .handle = NV_SUBDEV(THERM, 0xa3), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nva3_therm_ctor, - .dtor = _nouveau_therm_dtor, - .init = nva3_therm_init, - .fini = _nouveau_therm_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c deleted file mode 100644 index d7d30ee8332e..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c +++ /dev/null @@ -1,153 +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 "priv.h" - -struct nvd0_therm_priv { - struct nouveau_therm_priv base; -}; - -static int -pwm_info(struct nouveau_therm *therm, int line) -{ - u32 gpio = nv_rd32(therm, 0x00d610 + (line * 0x04)); - switch (gpio & 0x000000c0) { - case 0x00000000: /* normal mode, possibly pwm forced off by us */ - case 0x00000040: /* nvio special */ - switch (gpio & 0x0000001f) { - case 0x19: return 1; - case 0x1c: return 0; - default: - break; - } - default: - break; - } - - nv_error(therm, "GPIO %d unknown PWM: 0x%08x\n", line, gpio); - return -ENODEV; -} - -static int -nvd0_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable) -{ - u32 data = enable ? 0x00000040 : 0x00000000; - int indx = pwm_info(therm, line); - if (indx < 0) - return indx; - - nv_mask(therm, 0x00d610 + (line * 0x04), 0x000000c0, data); - return 0; -} - -static int -nvd0_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty) -{ - int indx = pwm_info(therm, line); - if (indx < 0) - return indx; - - if (nv_rd32(therm, 0x00d610 + (line * 0x04)) & 0x00000040) { - *divs = nv_rd32(therm, 0x00e114 + (indx * 8)); - *duty = nv_rd32(therm, 0x00e118 + (indx * 8)); - return 0; - } - - return -EINVAL; -} - -static int -nvd0_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty) -{ - int indx = pwm_info(therm, line); - if (indx < 0) - return indx; - - nv_wr32(therm, 0x00e114 + (indx * 8), divs); - nv_wr32(therm, 0x00e118 + (indx * 8), duty | 0x80000000); - return 0; -} - -static int -nvd0_fan_pwm_clock(struct nouveau_therm *therm) -{ - return (nv_device(therm)->crystal * 1000) / 20; -} - -static int -nvd0_therm_init(struct nouveau_object *object) -{ - struct nvd0_therm_priv *priv = (void *)object; - int ret; - - ret = nouveau_therm_init(&priv->base.base); - if (ret) - return ret; - - /* enable fan tach, count revolutions per-second */ - nv_mask(priv, 0x00e720, 0x00000003, 0x00000002); - if (priv->base.fan->tach.func != DCB_GPIO_UNUSED) { - nv_mask(priv, 0x00d79c, 0x000000ff, priv->base.fan->tach.line); - nv_wr32(priv, 0x00e724, nv_device(priv)->crystal * 1000); - nv_mask(priv, 0x00e720, 0x00000001, 0x00000001); - } - nv_mask(priv, 0x00e720, 0x00000002, 0x00000000); - - return 0; -} - -static int -nvd0_therm_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvd0_therm_priv *priv; - int ret; - - ret = nouveau_therm_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.base.pwm_ctrl = nvd0_fan_pwm_ctrl; - priv->base.base.pwm_get = nvd0_fan_pwm_get; - priv->base.base.pwm_set = nvd0_fan_pwm_set; - priv->base.base.pwm_clock = nvd0_fan_pwm_clock; - priv->base.base.temp_get = nv50_temp_get; - priv->base.base.fan_sense = nva3_therm_fan_sense; - priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling; - return nouveau_therm_preinit(&priv->base.base); -} - -struct nouveau_oclass -nvd0_therm_oclass = { - .handle = NV_SUBDEV(THERM, 0xd0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvd0_therm_ctor, - .dtor = _nouveau_therm_dtor, - .init = nvd0_therm_init, - .fini = _nouveau_therm_fini, - }, -}; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 06b98706b3fc..1c3cd6abc36e 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -1,6 +1,3 @@ -#ifndef __NVTHERM_PRIV_H__ -#define __NVTHERM_PRIV_H__ - /* * Copyright 2012 The Nouveau community * @@ -28,81 +25,33 @@ #include #include -#include #include #include -#include - -struct nouveau_fan { - struct nouveau_therm *parent; - const char *type; - - struct nvbios_therm_fan bios; - struct nvbios_perf_fan perf; - - struct nouveau_alarm alarm; - spinlock_t lock; - int percent; - - int (*get)(struct nouveau_therm *therm); - int (*set)(struct nouveau_therm *therm, int percent); - - struct dcb_gpio_func tach; -}; - -enum nouveau_therm_thrs_direction { - NOUVEAU_THERM_THRS_FALLING = 0, - NOUVEAU_THERM_THRS_RISING = 1 -}; - -enum nouveau_therm_thrs_state { - NOUVEAU_THERM_THRS_LOWER = 0, - NOUVEAU_THERM_THRS_HIGHER = 1 -}; - -enum nouveau_therm_thrs { - NOUVEAU_THERM_THRS_FANBOOST = 0, - NOUVEAU_THERM_THRS_DOWNCLOCK = 1, - NOUVEAU_THERM_THRS_CRITICAL = 2, - NOUVEAU_THERM_THRS_SHUTDOWN = 3, - NOUVEAU_THERM_THRS_NR -}; struct nouveau_therm_priv { struct nouveau_therm base; - /* automatic thermal management */ - struct nouveau_alarm alarm; - spinlock_t lock; - struct nouveau_therm_trip_point *last_trip; - int mode; - int suspend; - /* bios */ struct nvbios_therm_sensor bios_sensor; + struct nvbios_therm_fan bios_fan; + struct nvbios_perf_fan bios_perf_fan; /* fan priv */ - struct nouveau_fan *fan; - - /* alarms priv */ struct { - spinlock_t alarm_program_lock; - struct nouveau_alarm therm_poll_alarm; - enum nouveau_therm_thrs_state alarm_state[NOUVEAU_THERM_THRS_NR]; - void (*program_alarms)(struct nouveau_therm *); - } sensor; + enum nouveau_therm_fan_mode mode; + int percent; - /* what should be done if the card overheats */ - struct { - void (*downclock)(struct nouveau_therm *, bool active); - void (*pause)(struct nouveau_therm *, bool active); - } emergency; + int (*pwm_get)(struct nouveau_therm *, int line, u32*, u32*); + int (*pwm_set)(struct nouveau_therm *, int line, u32, u32); + int (*pwm_clock)(struct nouveau_therm *); + } fan; /* ic */ struct i2c_client *ic; }; -int nouveau_therm_mode(struct nouveau_therm *therm, int mode); +int nouveau_therm_init(struct nouveau_object *object); +int nouveau_therm_fini(struct nouveau_object *object, bool suspend); int nouveau_therm_attr_get(struct nouveau_therm *therm, enum nouveau_therm_attr_type type); int nouveau_therm_attr_set(struct nouveau_therm *therm, @@ -114,35 +63,11 @@ int nouveau_therm_sensor_ctor(struct nouveau_therm *therm); int nouveau_therm_fan_ctor(struct nouveau_therm *therm); int nouveau_therm_fan_get(struct nouveau_therm *therm); -int nouveau_therm_fan_set(struct nouveau_therm *therm, bool now, int percent); +int nouveau_therm_fan_set(struct nouveau_therm *therm, int percent); int nouveau_therm_fan_user_get(struct nouveau_therm *therm); int nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent); +int nouveau_therm_fan_set_mode(struct nouveau_therm *therm, + enum nouveau_therm_fan_mode mode); -int nouveau_therm_fan_sense(struct nouveau_therm *therm); - -int nouveau_therm_preinit(struct nouveau_therm *); -void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm, - enum nouveau_therm_thrs thrs, - enum nouveau_therm_thrs_state st); -enum nouveau_therm_thrs_state -nouveau_therm_sensor_get_threshold_state(struct nouveau_therm *therm, - enum nouveau_therm_thrs thrs); -void nouveau_therm_sensor_event(struct nouveau_therm *therm, - enum nouveau_therm_thrs thrs, - enum nouveau_therm_thrs_direction dir); -void nouveau_therm_program_alarms_polling(struct nouveau_therm *therm); - -int nv50_fan_pwm_ctrl(struct nouveau_therm *, int, bool); -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 nv50_temp_get(struct nouveau_therm *therm); - -int nva3_therm_fan_sense(struct nouveau_therm *); - -int nouveau_fanpwm_create(struct nouveau_therm *, struct dcb_gpio_func *); -int nouveau_fantog_create(struct nouveau_therm *, struct dcb_gpio_func *); -int nouveau_fannil_create(struct nouveau_therm *); - -#endif +int nouveau_therm_fan_sense(struct nouveau_therm *therm); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index b37624af8297..204282301fb1 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -58,171 +58,11 @@ static void nouveau_therm_temp_safety_checks(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; - struct nvbios_therm_sensor *s = &priv->bios_sensor; if (!priv->bios_sensor.slope_div) priv->bios_sensor.slope_div = 1; if (!priv->bios_sensor.offset_den) priv->bios_sensor.offset_den = 1; - - /* enforce a minimum hysteresis on thresholds */ - s->thrs_fan_boost.hysteresis = max_t(u8, s->thrs_fan_boost.hysteresis, 2); - s->thrs_down_clock.hysteresis = max_t(u8, s->thrs_down_clock.hysteresis, 2); - s->thrs_critical.hysteresis = max_t(u8, s->thrs_critical.hysteresis, 2); - s->thrs_shutdown.hysteresis = max_t(u8, s->thrs_shutdown.hysteresis, 2); -} - -/* must be called with alarm_program_lock taken ! */ -void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm, - enum nouveau_therm_thrs thrs, - enum nouveau_therm_thrs_state st) -{ - struct nouveau_therm_priv *priv = (void *)therm; - priv->sensor.alarm_state[thrs] = st; -} - -/* must be called with alarm_program_lock taken ! */ -enum nouveau_therm_thrs_state -nouveau_therm_sensor_get_threshold_state(struct nouveau_therm *therm, - enum nouveau_therm_thrs thrs) -{ - struct nouveau_therm_priv *priv = (void *)therm; - return priv->sensor.alarm_state[thrs]; -} - -static void -nv_poweroff_work(struct work_struct *work) -{ - orderly_poweroff(true); - kfree(work); -} - -void nouveau_therm_sensor_event(struct nouveau_therm *therm, - enum nouveau_therm_thrs thrs, - enum nouveau_therm_thrs_direction dir) -{ - struct nouveau_therm_priv *priv = (void *)therm; - bool active; - const char *thresolds[] = { - "fanboost", "downclock", "critical", "shutdown" - }; - uint8_t temperature = therm->temp_get(therm); - - if (thrs < 0 || thrs > 3) - return; - - if (dir == NOUVEAU_THERM_THRS_FALLING) - nv_info(therm, "temperature (%u C) went below the '%s' threshold\n", - temperature, thresolds[thrs]); - else - nv_info(therm, "temperature (%u C) hit the '%s' threshold\n", - temperature, thresolds[thrs]); - - active = (dir == NOUVEAU_THERM_THRS_RISING); - switch (thrs) { - case NOUVEAU_THERM_THRS_FANBOOST: - if (active) { - nouveau_therm_fan_set(therm, true, 100); - nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_AUTO); - } - break; - case NOUVEAU_THERM_THRS_DOWNCLOCK: - if (priv->emergency.downclock) - priv->emergency.downclock(therm, active); - break; - case NOUVEAU_THERM_THRS_CRITICAL: - if (priv->emergency.pause) - priv->emergency.pause(therm, active); - break; - case NOUVEAU_THERM_THRS_SHUTDOWN: - if (active) { - struct work_struct *work; - - work = kmalloc(sizeof(*work), GFP_ATOMIC); - if (work) { - INIT_WORK(work, nv_poweroff_work); - schedule_work(work); - } - } - break; - case NOUVEAU_THERM_THRS_NR: - break; - } - -} - -/* must be called with alarm_program_lock taken ! */ -static void -nouveau_therm_threshold_hyst_polling(struct nouveau_therm *therm, - const struct nvbios_therm_threshold *thrs, - enum nouveau_therm_thrs thrs_name) -{ - enum nouveau_therm_thrs_direction direction; - enum nouveau_therm_thrs_state prev_state, new_state; - int temp = therm->temp_get(therm); - - prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name); - - if (temp >= thrs->temp && prev_state == NOUVEAU_THERM_THRS_LOWER) { - direction = NOUVEAU_THERM_THRS_RISING; - new_state = NOUVEAU_THERM_THRS_HIGHER; - } else if (temp <= thrs->temp - thrs->hysteresis && - prev_state == NOUVEAU_THERM_THRS_HIGHER) { - direction = NOUVEAU_THERM_THRS_FALLING; - new_state = NOUVEAU_THERM_THRS_LOWER; - } else - return; /* nothing to do */ - - nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state); - nouveau_therm_sensor_event(therm, thrs_name, direction); -} - -static void -alarm_timer_callback(struct nouveau_alarm *alarm) -{ - struct nouveau_therm_priv *priv = - container_of(alarm, struct nouveau_therm_priv, sensor.therm_poll_alarm); - struct nvbios_therm_sensor *sensor = &priv->bios_sensor; - struct nouveau_timer *ptimer = nouveau_timer(priv); - struct nouveau_therm *therm = &priv->base; - unsigned long flags; - - spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags); - - nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_fan_boost, - NOUVEAU_THERM_THRS_FANBOOST); - - nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_down_clock, - NOUVEAU_THERM_THRS_DOWNCLOCK); - - nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_critical, - NOUVEAU_THERM_THRS_CRITICAL); - - nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_shutdown, - NOUVEAU_THERM_THRS_SHUTDOWN); - - /* schedule the next poll in one second */ - if (list_empty(&alarm->head)) - ptimer->alarm(ptimer, 1000 * 1000 * 1000, alarm); - - spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); -} - -void -nouveau_therm_program_alarms_polling(struct nouveau_therm *therm) -{ - struct nouveau_therm_priv *priv = (void *)therm; - struct nvbios_therm_sensor *sensor = &priv->bios_sensor; - - nv_info(therm, - "programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n", - sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis, - sensor->thrs_down_clock.temp, - sensor->thrs_down_clock.hysteresis, - sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis, - sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis); - - alarm_timer_callback(&priv->sensor.therm_poll_alarm); } int @@ -231,8 +71,6 @@ nouveau_therm_sensor_ctor(struct nouveau_therm *therm) struct nouveau_therm_priv *priv = (void *)therm; struct nouveau_bios *bios = nouveau_bios(therm); - nouveau_alarm_init(&priv->sensor.therm_poll_alarm, alarm_timer_callback); - nouveau_therm_temp_set_defaults(therm); if (nvbios_therm_sensor_parse(bios, NVBIOS_THERM_DOMAIN_CORE, &priv->bios_sensor)) diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c index 8e1bae4f12e8..c26ca9bef671 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c @@ -79,7 +79,7 @@ nv04_timer_alarm_trigger(struct nouveau_timer *ptimer) /* execute any pending alarm handlers */ list_for_each_entry_safe(alarm, atemp, &exec, head) { - list_del_init(&alarm->head); + list_del(&alarm->head); alarm->func(alarm); } } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.h b/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.h index 74acf0f87785..d0da230d7706 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.h @@ -3,7 +3,7 @@ #define ROM_BIOS_PAGE 4096 -#if defined(CONFIG_ACPI) && defined(CONFIG_X86) +#if defined(CONFIG_ACPI) bool nouveau_is_optimus(void); bool nouveau_is_v1_dsm(void); void nouveau_register_dsm_handler(void); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_backlight.c b/trunk/drivers/gpu/drm/nouveau/nouveau_backlight.c index 5d940302d2aa..f65b20a375f6 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -84,8 +84,6 @@ nv40_backlight_init(struct drm_connector *connector) props.max_brightness = 31; bd = backlight_device_register("nv_backlight", &connector->kdev, drm, &nv40_bl_ops, &props); - if (IS_ERR(bd)) - return PTR_ERR(bd); drm->backlight = bd; bd->props.brightness = nv40_get_intensity(bd); backlight_update_status(bd); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c index 50a6dd02f7c5..865eddfa30a7 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -678,6 +678,23 @@ int run_tmds_table(struct drm_device *dev, struct dcb_output *dcbent, int head, return 0; } +static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset) +{ + /* + * offset + 0 (8 bits): Micro version + * offset + 1 (8 bits): Minor version + * offset + 2 (8 bits): Chip version + * offset + 3 (8 bits): Major version + */ + struct nouveau_drm *drm = nouveau_drm(dev); + + bios->major_version = bios->data[offset + 3]; + bios->chip_version = bios->data[offset + 2]; + NV_INFO(drm, "Bios version %02x.%02x.%02x.%02x\n", + bios->data[offset + 3], bios->data[offset + 2], + bios->data[offset + 1], bios->data[offset]); +} + static void parse_script_table_pointers(struct nvbios *bios, uint16_t offset) { /* @@ -693,6 +710,12 @@ static void parse_script_table_pointers(struct nvbios *bios, uint16_t offset) */ bios->init_script_tbls_ptr = ROM16(bios->data[offset]); + bios->macro_index_tbl_ptr = ROM16(bios->data[offset + 2]); + bios->macro_tbl_ptr = ROM16(bios->data[offset + 4]); + bios->condition_tbl_ptr = ROM16(bios->data[offset + 6]); + bios->io_condition_tbl_ptr = ROM16(bios->data[offset + 8]); + bios->io_flag_condition_tbl_ptr = ROM16(bios->data[offset + 10]); + bios->init_function_tbl_ptr = ROM16(bios->data[offset + 12]); } static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) @@ -742,6 +765,25 @@ static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, st return 0; } +static int parse_bit_C_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) +{ + /* + * offset + 8 (16 bits): PLL limits table pointer + * + * There's more in here, but that's unknown. + */ + struct nouveau_drm *drm = nouveau_drm(dev); + + if (bitentry->length < 10) { + NV_ERROR(drm, "Do not understand BIT C table\n"); + return -EINVAL; + } + + bios->pll_limit_tbl_ptr = ROM16(bios->data[bitentry->offset + 8]); + + return 0; +} + static int parse_bit_display_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) { /* @@ -779,6 +821,12 @@ static int parse_bit_init_tbl_entry(struct drm_device *dev, struct nvbios *bios, } parse_script_table_pointers(bios, bitentry->offset); + + if (bitentry->length >= 16) + bios->some_script_ptr = ROM16(bios->data[bitentry->offset + 14]); + if (bitentry->length >= 18) + bios->init96_tbl_ptr = ROM16(bios->data[bitentry->offset + 16]); + return 0; } @@ -804,6 +852,8 @@ static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, st return -EINVAL; } + parse_bios_version(dev, bios, bitentry->offset); + /* * bit 4 seems to indicate a mobile bios (doesn't suffer from BMP's * Quadro identity crisis), other bits possibly as for BMP feature byte @@ -1028,6 +1078,9 @@ parse_bit_structure(struct nvbios *bios, const uint16_t bitoffset) return ret; if (bios->major_version >= 0x60) /* g80+ */ parse_bit_table(bios, bitoffset, &BIT_TABLE('A', A)); + ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('C', C)); + if (ret) + return ret; parse_bit_table(bios, bitoffset, &BIT_TABLE('D', display)); ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('I', init)); if (ret) @@ -1175,6 +1228,8 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi */ bios->feature_byte = bmp[9]; + parse_bios_version(dev, bios, offset + 10); + if (bmp_version_major < 5 || bmp_version_minor < 0x10) bios->old_style_init = true; legacy_scripts_offset = 18; @@ -1221,10 +1276,8 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi bios->fp.lvdsmanufacturerpointer = ROM16(bmp[117]); bios->fp.fpxlatemanufacturertableptr = ROM16(bmp[119]); } -#if 0 if (bmplength > 143) bios->pll_limit_tbl_ptr = ROM16(bmp[142]); -#endif if (bmplength > 157) bios->fp.duallink_transition_clk = ROM16(bmp[156]) * 10; @@ -1469,7 +1522,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, } case DCB_OUTPUT_DP: entry->dpconf.sor.link = (conf & 0x00000030) >> 4; - entry->extdev = (conf & 0x0000ff00) >> 8; switch ((conf & 0x00e00000) >> 21) { case 0: entry->dpconf.link_bw = 162000; @@ -1491,10 +1543,8 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, } break; case DCB_OUTPUT_TMDS: - if (dcb->version >= 0x40) { + if (dcb->version >= 0x40) entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4; - entry->extdev = (conf & 0x0000ff00) >> 8; - } else if (dcb->version >= 0x30) entry->tmdsconf.slave_addr = (conf & 0x00000700) >> 8; else if (dcb->version >= 0x22) @@ -1887,9 +1937,9 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios) if (conn[0] != 0xff) { NV_INFO(drm, "DCB conn %02d: ", idx); if (olddcb_conntab(dev)[3] < 4) - pr_cont("%04x\n", ROM16(conn[0])); + printk("%04x\n", ROM16(conn[0])); else - pr_cont("%08x\n", ROM32(conn[0])); + printk("%08x\n", ROM32(conn[0])); } } dcb_fake_connectors(bios); @@ -2002,29 +2052,45 @@ uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) static bool NVInitVBIOS(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_bios *bios = nouveau_bios(drm->device); - struct nvbios *legacy = &drm->vbios; - - memset(legacy, 0, sizeof(struct nvbios)); - spin_lock_init(&legacy->lock); - legacy->dev = dev; - - legacy->data = bios->data; - legacy->length = bios->size; - legacy->major_version = bios->version.major; - legacy->chip_version = bios->version.chip; - if (bios->bit_offset) { - legacy->type = NVBIOS_BIT; - legacy->offset = bios->bit_offset; - return !parse_bit_structure(legacy, legacy->offset + 6); - } else - if (bios->bmp_offset) { - legacy->type = NVBIOS_BMP; - legacy->offset = bios->bmp_offset; - return !parse_bmp_structure(dev, legacy, legacy->offset); - } + struct nvbios *bios = &drm->vbios; - return false; + memset(bios, 0, sizeof(struct nvbios)); + spin_lock_init(&bios->lock); + bios->dev = dev; + + bios->data = nouveau_bios(drm->device)->data; + bios->length = nouveau_bios(drm->device)->size; + return true; +} + +static int nouveau_parse_vbios_struct(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvbios *bios = &drm->vbios; + const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' }; + const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 }; + int offset; + + offset = findstr(bios->data, bios->length, + bit_signature, sizeof(bit_signature)); + if (offset) { + NV_INFO(drm, "BIT BIOS found\n"); + bios->type = NVBIOS_BIT; + bios->offset = offset; + return parse_bit_structure(bios, offset + 6); + } + + offset = findstr(bios->data, bios->length, + bmp_signature, sizeof(bmp_signature)); + if (offset) { + NV_INFO(drm, "BMP BIOS found\n"); + bios->type = NVBIOS_BMP; + bios->offset = offset; + return parse_bmp_structure(dev, bios, offset); + } + + NV_ERROR(drm, "No known BIOS signature found\n"); + return -ENODEV; } int @@ -2080,6 +2146,10 @@ nouveau_bios_init(struct drm_device *dev) if (!NVInitVBIOS(dev)) return -ENODEV; + ret = nouveau_parse_vbios_struct(dev); + if (ret) + return ret; + ret = parse_dcb_table(dev, bios); if (ret) return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h index 7ccd28f11adf..f68c54ca422f 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -107,10 +107,20 @@ struct nvbios { bool old_style_init; uint16_t init_script_tbls_ptr; uint16_t extra_init_script_tbl_ptr; - + uint16_t macro_index_tbl_ptr; + uint16_t macro_tbl_ptr; + uint16_t condition_tbl_ptr; + uint16_t io_condition_tbl_ptr; + uint16_t io_flag_condition_tbl_ptr; + uint16_t init_function_tbl_ptr; + + uint16_t pll_limit_tbl_ptr; uint16_t ram_restrict_tbl_ptr; uint8_t ram_restrict_group_count; + uint16_t some_script_ptr; /* BIT I + 14 */ + uint16_t init96_tbl_ptr; /* BIT I + 16 */ + struct dcb_table dcb; struct { diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c index 11ca82148edc..2f2741483b51 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -562,7 +562,7 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, struct nouveau_fence *fence = NULL; int ret; - ret = nouveau_fence_new(chan, false, &fence); + ret = nouveau_fence_new(chan, &fence); if (ret) return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_chan.c b/trunk/drivers/gpu/drm/nouveau/nouveau_chan.c index eaa80a2b81ee..174300b6a02e 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -51,15 +51,14 @@ nouveau_channel_idle(struct nouveau_channel *chan) struct nouveau_fence *fence = NULL; int ret; - ret = nouveau_fence_new(chan, false, &fence); + ret = nouveau_fence_new(chan, &fence); if (!ret) { ret = nouveau_fence_wait(fence, false, false); nouveau_fence_unref(&fence); } if (ret) - NV_ERROR(cli, "failed to idle channel 0x%08x [%s]\n", - chan->handle, cli->base.name); + NV_ERROR(cli, "failed to idle channel 0x%08x\n", chan->handle); return ret; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index 4dd7ae2ac6c6..e620ba8271b4 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -55,6 +55,8 @@ MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)"); static int nouveau_duallink = 1; module_param_named(duallink, nouveau_duallink, int, 0400); +static void nouveau_connector_hotplug(void *, int); + struct nouveau_encoder * find_encoder(struct drm_connector *connector, int type) { @@ -98,6 +100,22 @@ static void nouveau_connector_destroy(struct drm_connector *connector) { struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nouveau_gpio *gpio; + struct nouveau_drm *drm; + struct drm_device *dev; + + if (!nv_connector) + return; + + dev = nv_connector->base.dev; + drm = nouveau_drm(dev); + gpio = nouveau_gpio(drm->device); + + if (gpio && nv_connector->hpd != DCB_GPIO_UNUSED) { + gpio->isr_del(gpio, 0, nv_connector->hpd, 0xff, + nouveau_connector_hotplug, connector); + } + kfree(nv_connector->edid); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); @@ -112,6 +130,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_gpio *gpio = nouveau_gpio(drm->device); + struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_i2c_port *port = NULL; int i, panel = -ENODEV; @@ -141,7 +160,8 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, continue; nv_encoder = nouveau_encoder(obj_to_encoder(obj)); - port = nv_encoder->i2c; + if (nv_encoder->dcb->i2c_index < 0xf) + port = i2c->find(i2c, nv_encoder->dcb->i2c_index); if (port && nv_probe_i2c(port, 0x50)) { *pnv_encoder = nv_encoder; break; @@ -379,10 +399,9 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) struct edid *edid = (struct edid *)nouveau_bios_embedded_edid(dev); if (edid) { - nv_connector->edid = - kmemdup(edid, EDID_LENGTH, GFP_KERNEL); - if (nv_connector->edid) - status = connector_status_connected; + nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + *(nv_connector->edid) = *edid; + status = connector_status_connected; } } @@ -892,37 +911,6 @@ nouveau_connector_funcs_lvds = { .force = nouveau_connector_force }; -static void -nouveau_connector_hotplug_work(struct work_struct *work) -{ - struct nouveau_connector *nv_connector = - container_of(work, struct nouveau_connector, hpd_work); - struct drm_connector *connector = &nv_connector->base; - struct drm_device *dev = connector->dev; - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_gpio *gpio = nouveau_gpio(drm->device); - bool plugged = gpio->get(gpio, 0, nv_connector->hpd.func, 0xff); - - NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", - drm_get_connector_name(connector)); - - if (plugged) - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - else - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - - drm_helper_hpd_irq_event(dev); -} - -static int -nouveau_connector_hotplug(struct nouveau_eventh *event, int index) -{ - struct nouveau_connector *nv_connector = - container_of(event, struct nouveau_connector, hpd_func); - schedule_work(&nv_connector->hpd_work); - return NVKM_EVENT_KEEP; -} - static int drm_conntype_from_dcb(enum dcb_connector_type dcb) { @@ -973,7 +961,6 @@ nouveau_connector_create(struct drm_device *dev, int index) return ERR_PTR(-ENOMEM); connector = &nv_connector->base; - INIT_WORK(&nv_connector->hpd_work, nouveau_connector_hotplug_work); nv_connector->index = index; /* attempt to parse vbios connector type and hotplug gpio */ @@ -988,11 +975,8 @@ nouveau_connector_create(struct drm_device *dev, int index) if (olddcb_conntab(dev)[3] >= 4) entry |= (u32)ROM16(nv_connector->dcb[2]) << 16; - 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; + nv_connector->hpd = ffs((entry & 0x07033000) >> 12); + nv_connector->hpd = hpd[nv_connector->hpd]; nv_connector->type = nv_connector->dcb[0]; if (drm_conntype_from_dcb(nv_connector->type) == @@ -1015,7 +999,7 @@ nouveau_connector_create(struct drm_device *dev, int index) } } else { nv_connector->type = DCB_CONNECTOR_NONE; - nv_connector->hpd.func = DCB_GPIO_UNUSED; + nv_connector->hpd = DCB_GPIO_UNUSED; } /* no vbios data, or an unknown dcb connector type - attempt to @@ -1142,9 +1126,31 @@ nouveau_connector_create(struct drm_device *dev, int index) } connector->polled = DRM_CONNECTOR_POLL_CONNECT; - if (nv_connector->hpd.func != DCB_GPIO_UNUSED) - connector->polled = DRM_CONNECTOR_POLL_HPD; + if (gpio && nv_connector->hpd != DCB_GPIO_UNUSED) { + ret = gpio->isr_add(gpio, 0, nv_connector->hpd, 0xff, + nouveau_connector_hotplug, connector); + if (ret == 0) + connector->polled = DRM_CONNECTOR_POLL_HPD; + } drm_sysfs_connector_add(connector); return connector; } + +static void +nouveau_connector_hotplug(void *data, int plugged) +{ + struct drm_connector *connector = data; + struct drm_device *dev = connector->dev; + struct nouveau_drm *drm = nouveau_drm(dev); + + NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", + drm_get_connector_name(connector)); + + if (plugged) + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); + else + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); + + drm_helper_hpd_irq_event(dev); +} diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.h b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.h index 6e399aad491a..20eb84cce9e6 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -30,11 +30,6 @@ #include #include "nouveau_crtc.h" -#include - -#include -#include - struct nouveau_i2c_port; enum nouveau_underscan_type { @@ -66,10 +61,7 @@ struct nouveau_connector { enum dcb_connector_type type; u8 index; u8 *dcb; - - struct dcb_gpio_func hpd; - struct work_struct hpd_work; - struct nouveau_eventh hpd_func; + u8 hpd; int dithering_mode; int dithering_depth; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.c deleted file mode 100644 index 5392e07edfc6..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat - * - * 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 COPYRIGHT OWNER(S) 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: - * Ben Skeggs - */ - -#include "nouveau_debugfs.h" -#include "nouveau_drm.h" - -static int -nouveau_debugfs_vbios_image(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct nouveau_drm *drm = nouveau_drm(node->minor->dev); - int i; - - for (i = 0; i < drm->vbios.length; i++) - seq_printf(m, "%c", drm->vbios.data[i]); - return 0; -} - -static struct drm_info_list nouveau_debugfs_list[] = { - { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL }, -}; -#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) - -int -nouveau_debugfs_init(struct drm_minor *minor) -{ - drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES, - minor->debugfs_root, minor); - return 0; -} - -void -nouveau_debugfs_takedown(struct drm_minor *minor) -{ - drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES, - minor); -} diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.h b/trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.h deleted file mode 100644 index a62af6fb5f99..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_debugfs.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __NOUVEAU_DEBUGFS_H__ -#define __NOUVEAU_DEBUGFS_H__ - -#include - -#if defined(CONFIG_DEBUG_FS) -extern int nouveau_debugfs_init(struct drm_minor *); -extern void nouveau_debugfs_takedown(struct drm_minor *); -#else -static inline int -nouveau_debugfs_init(struct drm_minor *minor) -{ - return 0; -} - -static inline void nouveau_debugfs_takedown(struct drm_minor *minor) -{ -} - -#endif - -#endif diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 4610c3a29bbe..d42c9e860c16 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -41,8 +41,6 @@ #include #include -#include - static void nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) { @@ -233,10 +231,8 @@ 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 (gpio && conn->hpd.func != DCB_GPIO_UNUSED) { - nouveau_event_get(gpio->events, conn->hpd.line, - &conn->hpd_func); - } + if (gpio) + gpio->irq(gpio, 0, conn->hpd, 0xff, true); } return ret; @@ -253,20 +249,37 @@ nouveau_display_fini(struct drm_device *dev) /* disable hotplug interrupts */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); - if (gpio && conn->hpd.func != DCB_GPIO_UNUSED) { - nouveau_event_put(gpio->events, conn->hpd.line, - &conn->hpd_func); - } + if (gpio) + gpio->irq(gpio, 0, conn->hpd, 0xff, false); } drm_kms_helper_poll_disable(dev); disp->fini(dev); } +static void +nouveau_display_vblank_notify(void *data, int crtc) +{ + drm_handle_vblank(data, crtc); +} + +static void +nouveau_display_vblank_get(void *data, int crtc) +{ + drm_vblank_get(data, crtc); +} + +static void +nouveau_display_vblank_put(void *data, int crtc) +{ + drm_vblank_put(data, crtc); +} + int nouveau_display_create(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_disp *pdisp = nouveau_disp(drm->device); struct nouveau_display *disp; u32 pclass = dev->pdev->class >> 8; int ret, gen; @@ -275,6 +288,11 @@ nouveau_display_create(struct drm_device *dev) if (!disp) return -ENOMEM; + pdisp->vblank.data = dev; + pdisp->vblank.notify = nouveau_display_vblank_notify; + pdisp->vblank.get = nouveau_display_vblank_get; + pdisp->vblank.put = nouveau_display_vblank_put; + drm_mode_config_init(dev); drm_mode_create_scaling_mode_property(dev); drm_mode_create_dvi_i_properties(dev); @@ -298,13 +316,17 @@ nouveau_display_create(struct drm_device *dev) drm_property_create_range(dev, 0, "underscan vborder", 0, 128); if (gen >= 1) { - /* -90..+90 */ disp->vibrant_hue_property = - drm_property_create_range(dev, 0, "vibrant hue", 0, 180); + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "vibrant hue", 2); + disp->vibrant_hue_property->values[0] = 0; + disp->vibrant_hue_property->values[1] = 180; /* -90..+90 */ - /* -100..+100 */ disp->color_vibrance_property = - drm_property_create_range(dev, 0, "color vibrance", 0, 200); + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "color vibrance", 2); + disp->color_vibrance_property->values[0] = 0; + disp->color_vibrance_property->values[1] = 200; /* -100..+100 */ } dev->mode_config.funcs = &nouveau_mode_config_funcs; @@ -456,6 +478,39 @@ nouveau_display_resume(struct drm_device *dev) } } +int +nouveau_vblank_enable(struct drm_device *dev, int crtc) +{ + struct nouveau_device *device = nouveau_dev(dev); + + if (device->card_type >= NV_D0) + nv_mask(device, 0x6100c0 + (crtc * 0x800), 1, 1); + else + if (device->card_type >= NV_50) + nv_mask(device, NV50_PDISPLAY_INTR_EN_1, 0, + NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc)); + else + NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, + NV_PCRTC_INTR_0_VBLANK); + + return 0; +} + +void +nouveau_vblank_disable(struct drm_device *dev, int crtc) +{ + struct nouveau_device *device = nouveau_dev(dev); + + if (device->card_type >= NV_D0) + nv_mask(device, 0x6100c0 + (crtc * 0x800), 1, 0); + else + if (device->card_type >= NV_50) + nv_mask(device, NV50_PDISPLAY_INTR_EN_1, + NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0); + else + NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0); +} + static int nouveau_page_flip_reserve(struct nouveau_bo *old_bo, struct nouveau_bo *new_bo) @@ -540,7 +595,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, } FIRE_RING (chan); - ret = nouveau_fence_new(chan, false, pfence); + ret = nouveau_fence_new(chan, pfence); if (ret) goto fail; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.h b/trunk/drivers/gpu/drm/nouveau/nouveau_display.h index 1ea3e4734b62..722548bb3bd3 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.h @@ -59,6 +59,9 @@ void nouveau_display_fini(struct drm_device *dev); int nouveau_display_suspend(struct drm_device *dev); void nouveau_display_resume(struct drm_device *dev); +int nouveau_vblank_enable(struct drm_device *dev, int crtc); +void nouveau_vblank_disable(struct drm_device *dev, int crtc); + int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event); int nouveau_finish_page_flip(struct nouveau_channel *, diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h b/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h index 690d5930ce32..5c2e22932d1c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -191,7 +191,7 @@ WIND_RING(struct nouveau_channel *chan) #define NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG 0x00000002 #define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL 0x00000004 #define NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD 0x00001000 -#define NV84_SUBCHAN_UEVENT 0x00000020 +#define NV84_SUBCHAN_NOTIFY_INTR 0x00000020 #define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024 #define NV10_SUBCHAN_REF_CNT 0x00000050 #define NVSW_SUBCHAN_PAGE_FLIP 0x00000054 diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_dp.c b/trunk/drivers/gpu/drm/nouveau/nouveau_dp.c index 36fd22500569..59838651ee8f 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -35,6 +35,300 @@ #include #include +/****************************************************************************** + * link training + *****************************************************************************/ +struct dp_state { + struct nouveau_i2c_port *auxch; + struct nouveau_object *core; + struct dcb_output *dcb; + int crtc; + u8 *dpcd; + int link_nr; + u32 link_bw; + u8 stat[6]; + u8 conf[4]; +}; + +static void +dp_set_link_config(struct drm_device *dev, struct dp_state *dp) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct dcb_output *dcb = dp->dcb; + const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); + const u32 moff = (dp->crtc << 3) | (link << 2) | or; + u8 sink[2]; + u32 data; + + NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); + + /* set desired link configuration on the source */ + data = ((dp->link_bw / 27000) << 8) | dp->link_nr; + if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) + data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH; + + nv_call(dp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data); + + /* inform the sink of the new configuration */ + sink[0] = dp->link_bw / 27000; + sink[1] = dp->link_nr; + if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) + sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; + + nv_wraux(dp->auxch, DP_LINK_BW_SET, sink, 2); +} + +static void +dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct dcb_output *dcb = dp->dcb; + const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); + const u32 moff = (dp->crtc << 3) | (link << 2) | or; + u8 sink_tp; + + NV_DEBUG(drm, "training pattern %d\n", pattern); + + nv_call(dp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern); + + nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); + sink_tp &= ~DP_TRAINING_PATTERN_MASK; + sink_tp |= pattern; + nv_wraux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); +} + +static int +dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct dcb_output *dcb = dp->dcb; + const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); + const u32 moff = (dp->crtc << 3) | (link << 2) | or; + int i; + + for (i = 0; i < dp->link_nr; i++) { + u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf; + u8 lpre = (lane & 0x0c) >> 2; + u8 lvsw = (lane & 0x03) >> 0; + + dp->conf[i] = (lpre << 3) | lvsw; + if (lvsw == DP_TRAIN_VOLTAGE_SWING_1200) + dp->conf[i] |= DP_TRAIN_MAX_SWING_REACHED; + if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5) + dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; + + NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]); + + nv_call(dp->core, NV94_DISP_SOR_DP_DRVCTL(i) + moff, (lvsw << 8) | lpre); + } + + return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4); +} + +static int +dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + int ret; + + udelay(delay); + + ret = nv_rdaux(dp->auxch, DP_LANE0_1_STATUS, dp->stat, 6); + if (ret) + return ret; + + NV_DEBUG(drm, "status %*ph\n", 6, dp->stat); + return 0; +} + +static int +dp_link_train_cr(struct drm_device *dev, struct dp_state *dp) +{ + bool cr_done = false, abort = false; + int voltage = dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK; + int tries = 0, i; + + dp_set_training_pattern(dev, dp, DP_TRAINING_PATTERN_1); + + do { + if (dp_link_train_commit(dev, dp) || + dp_link_train_update(dev, dp, 100)) + break; + + cr_done = true; + for (i = 0; i < dp->link_nr; i++) { + u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; + if (!(lane & DP_LANE_CR_DONE)) { + cr_done = false; + if (dp->conf[i] & DP_TRAIN_MAX_SWING_REACHED) + abort = true; + break; + } + } + + if ((dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { + voltage = dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK; + tries = 0; + } + } while (!cr_done && !abort && ++tries < 5); + + return cr_done ? 0 : -1; +} + +static int +dp_link_train_eq(struct drm_device *dev, struct dp_state *dp) +{ + bool eq_done, cr_done = true; + int tries = 0, i; + + dp_set_training_pattern(dev, dp, DP_TRAINING_PATTERN_2); + + do { + if (dp_link_train_update(dev, dp, 400)) + break; + + eq_done = !!(dp->stat[2] & DP_INTERLANE_ALIGN_DONE); + for (i = 0; i < dp->link_nr && eq_done; i++) { + u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; + if (!(lane & DP_LANE_CR_DONE)) + cr_done = false; + if (!(lane & DP_LANE_CHANNEL_EQ_DONE) || + !(lane & DP_LANE_SYMBOL_LOCKED)) + eq_done = false; + } + + if (dp_link_train_commit(dev, dp)) + break; + } while (!eq_done && cr_done && ++tries <= 5); + + return eq_done ? 0 : -1; +} + +static void +dp_link_train_init(struct drm_device *dev, struct dp_state *dp, bool spread) +{ + struct dcb_output *dcb = dp->dcb; + const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); + const u32 moff = (dp->crtc << 3) | (link << 2) | or; + + nv_call(dp->core, NV94_DISP_SOR_DP_TRAIN + moff, (spread ? + NV94_DISP_SOR_DP_TRAIN_INIT_SPREAD_ON : + NV94_DISP_SOR_DP_TRAIN_INIT_SPREAD_OFF) | + NV94_DISP_SOR_DP_TRAIN_OP_INIT); +} + +static void +dp_link_train_fini(struct drm_device *dev, struct dp_state *dp) +{ + struct dcb_output *dcb = dp->dcb; + const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); + const u32 moff = (dp->crtc << 3) | (link << 2) | or; + + nv_call(dp->core, NV94_DISP_SOR_DP_TRAIN + moff, + NV94_DISP_SOR_DP_TRAIN_OP_FINI); +} + +static bool +nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, + struct nouveau_object *core) +{ + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); + struct nouveau_connector *nv_connector = + nouveau_encoder_connector_get(nv_encoder); + struct drm_device *dev = encoder->dev; + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_i2c *i2c = nouveau_i2c(drm->device); + struct nouveau_gpio *gpio = nouveau_gpio(drm->device); + const u32 bw_list[] = { 270000, 162000, 0 }; + const u32 *link_bw = bw_list; + struct dp_state dp; + + dp.auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); + if (!dp.auxch) + return false; + + dp.core = core; + dp.dcb = nv_encoder->dcb; + dp.crtc = nv_crtc->index; + dp.dpcd = nv_encoder->dp.dpcd; + + /* adjust required bandwidth for 8B/10B coding overhead */ + datarate = (datarate / 8) * 10; + + /* some sinks toggle hotplug in response to some of the actions + * we take during link training (DP_SET_POWER is one), we need + * to ignore them for the moment to avoid races. + */ + gpio->irq(gpio, 0, nv_connector->hpd, 0xff, false); + + /* enable down-spreading and execute pre-train script from vbios */ + dp_link_train_init(dev, &dp, nv_encoder->dp.dpcd[3] & 1); + + /* start off at highest link rate supported by encoder and display */ + while (*link_bw > nv_encoder->dp.link_bw) + link_bw++; + + while (link_bw[0]) { + /* find minimum required lane count at this link rate */ + dp.link_nr = nv_encoder->dp.link_nr; + while ((dp.link_nr >> 1) * link_bw[0] > datarate) + dp.link_nr >>= 1; + + /* drop link rate to minimum with this lane count */ + while ((link_bw[1] * dp.link_nr) > datarate) + link_bw++; + dp.link_bw = link_bw[0]; + + /* program selected link configuration */ + dp_set_link_config(dev, &dp); + + /* attempt to train the link at this configuration */ + memset(dp.stat, 0x00, sizeof(dp.stat)); + if (!dp_link_train_cr(dev, &dp) && + !dp_link_train_eq(dev, &dp)) + break; + + /* retry at lower rate */ + link_bw++; + } + + /* finish link training */ + dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE); + + /* execute post-train script from vbios */ + dp_link_train_fini(dev, &dp); + + /* re-enable hotplug detect */ + gpio->irq(gpio, 0, nv_connector->hpd, 0xff, true); + return true; +} + +void +nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, + struct nouveau_object *core) +{ + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nouveau_drm *drm = nouveau_drm(encoder->dev); + struct nouveau_i2c *i2c = nouveau_i2c(drm->device); + struct nouveau_i2c_port *auxch; + u8 status; + + auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); + if (!auxch) + return; + + if (mode == DRM_MODE_DPMS_ON) + status = DP_SET_POWER_D0; + else + status = DP_SET_POWER_D3; + + nv_wraux(auxch, DP_SET_POWER, &status, 1); + + if (mode == DRM_MODE_DPMS_ON) + nouveau_dp_link_train(encoder, datarate, core); +} + static void nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch, u8 *dpcd) @@ -61,11 +355,12 @@ nouveau_dp_detect(struct drm_encoder *encoder) struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_device *dev = encoder->dev; struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_i2c_port *auxch; u8 *dpcd = nv_encoder->dp.dpcd; int ret; - auxch = nv_encoder->i2c; + auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); if (!auxch) return false; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index 8a03c58ae988..8e8e8ce75528 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -34,8 +34,6 @@ #include #include -#include - #include "nouveau_drm.h" #include "nouveau_irq.h" #include "nouveau_dma.h" @@ -50,7 +48,6 @@ #include "nouveau_abi16.h" #include "nouveau_fbcon.h" #include "nouveau_fence.h" -#include "nouveau_debugfs.h" MODULE_PARM_DESC(config, "option string to pass to driver core"); static char *nouveau_config; @@ -71,32 +68,6 @@ module_param_named(modeset, nouveau_modeset, int, 0400); static struct drm_driver driver; -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); - nouveau_event_get(pdisp->vblank, head, &drm->vblank); - 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); - nouveau_event_put(pdisp->vblank, head, &drm->vblank); -} - -static int -nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) -{ - struct nouveau_drm *drm = - container_of(event, struct nouveau_drm, vblank); - drm_handle_vblank(drm->dev, head); - return NVKM_EVENT_KEEP; -} - static u64 nouveau_name(struct pci_dev *pdev) { @@ -161,8 +132,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->chipset < 0x17) ret = nv10_fence_create(drm); - else if (device->card_type < NV_50) ret = nv17_fence_create(drm); + else if (device->card_type < NV_50) ret = nv10_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); else ret = nvc0_fence_create(drm); @@ -289,7 +259,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) dev->dev_private = drm; drm->dev = dev; - drm->vblank.func = nouveau_drm_vblank_handler; INIT_LIST_HEAD(&drm->clients); spin_lock_init(&drm->tile.lock); @@ -429,7 +398,7 @@ nouveau_drm_remove(struct pci_dev *pdev) nouveau_object_debug(); } -static int +int nouveau_do_suspend(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); @@ -500,7 +469,7 @@ int nouveau_pmops_suspend(struct device *dev) return 0; } -static int +int nouveau_do_resume(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); @@ -574,11 +543,10 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) struct pci_dev *pdev = dev->pdev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_cli *cli; - char name[32], tmpname[TASK_COMM_LEN]; + char name[16]; int ret; - get_task_comm(tmpname, current); - snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid)); + snprintf(name, sizeof(name), "%d", pid_nr(fpriv->pid)); ret = nouveau_cli_create(pdev, name, sizeof(*cli), (void **)&cli); if (ret) @@ -668,19 +636,14 @@ driver = { .postclose = nouveau_drm_postclose, .lastclose = nouveau_vga_lastclose, -#if defined(CONFIG_DEBUG_FS) - .debugfs_init = nouveau_debugfs_init, - .debugfs_cleanup = nouveau_debugfs_takedown, -#endif - .irq_preinstall = nouveau_irq_preinstall, .irq_postinstall = nouveau_irq_postinstall, .irq_uninstall = nouveau_irq_uninstall, .irq_handler = nouveau_irq_handler, .get_vblank_counter = drm_vblank_count, - .enable_vblank = nouveau_drm_vblank_enable, - .disable_vblank = nouveau_drm_vblank_disable, + .enable_vblank = nouveau_vblank_enable, + .disable_vblank = nouveau_vblank_disable, .ioctls = nouveau_ioctls, .fops = &nouveau_driver_fops, diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h index b25df374c901..aa89eb938b47 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -13,7 +13,6 @@ #define DRIVER_PATCHLEVEL 0 #include -#include #include @@ -113,7 +112,6 @@ struct nouveau_drm { struct nvbios vbios; struct nouveau_display *display; struct backlight_device *backlight; - struct nouveau_eventh vblank; /* power management */ struct nouveau_pm *pm; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_encoder.h b/trunk/drivers/gpu/drm/nouveau/nouveau_encoder.h index e24341229d5e..d0d95bd511ab 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -36,12 +36,19 @@ struct nouveau_i2c_port; +struct dp_train_func { + void (*link_set)(struct drm_device *, struct dcb_output *, int crtc, + int nr, u32 bw, bool enhframe); + void (*train_set)(struct drm_device *, struct dcb_output *, u8 pattern); + void (*train_adj)(struct drm_device *, struct dcb_output *, + u8 lane, u8 swing, u8 preem); +}; + struct nouveau_encoder { struct drm_encoder_slave base; struct dcb_output *dcb; int or; - struct nouveau_i2c_port *i2c; /* different to drm_encoder.crtc, this reflects what's * actually programmed on the hw, not the proposed crtc */ diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.c b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.c index 6c946837a0aa..1d049be79f74 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -33,14 +33,14 @@ #include "nouveau_dma.h" #include "nouveau_fence.h" -#include - void nouveau_fence_context_del(struct nouveau_fence_chan *fctx) { struct nouveau_fence *fence, *fnext; spin_lock(&fctx->lock); list_for_each_entry_safe(fence, fnext, &fctx->pending, head) { + if (fence->work) + fence->work(fence->priv, false); fence->channel = NULL; list_del(&fence->head); nouveau_fence_unref(&fence); @@ -59,14 +59,17 @@ nouveau_fence_context_new(struct nouveau_fence_chan *fctx) static void nouveau_fence_update(struct nouveau_channel *chan) { + struct nouveau_fence_priv *priv = chan->drm->fence; struct nouveau_fence_chan *fctx = chan->fence; struct nouveau_fence *fence, *fnext; spin_lock(&fctx->lock); list_for_each_entry_safe(fence, fnext, &fctx->pending, head) { - if (fctx->read(chan) < fence->sequence) + if (priv->read(chan) < fence->sequence) break; + if (fence->work) + fence->work(fence->priv, true); fence->channel = NULL; list_del(&fence->head); nouveau_fence_unref(&fence); @@ -77,6 +80,7 @@ nouveau_fence_update(struct nouveau_channel *chan) int nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) { + struct nouveau_fence_priv *priv = chan->drm->fence; struct nouveau_fence_chan *fctx = chan->fence; int ret; @@ -84,7 +88,7 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) fence->timeout = jiffies + (3 * DRM_HZ); fence->sequence = ++fctx->sequence; - ret = fctx->emit(fence); + ret = priv->emit(fence); if (!ret) { kref_get(&fence->kref); spin_lock(&fctx->lock); @@ -103,87 +107,13 @@ 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(struct nouveau_eventh *event, int index) -{ - struct nouveau_fence_uevent *uevent = - container_of(event, struct nouveau_fence_uevent, handler); - wake_up_all(&uevent->priv->waiting); - return NVKM_EVENT_KEEP; -} - -static int -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_fence_uevent uevent = { - .handler.func = nouveau_fence_wait_uevent_handler, - .priv = priv, - }; - int ret = 0; - - nouveau_event_get(pfifo->uevent, 0, &uevent.handler); - - if (fence->timeout) { - unsigned long timeout = fence->timeout - jiffies; - - if (time_before(jiffies, fence->timeout)) { - if (intr) { - ret = wait_event_interruptible_timeout( - priv->waiting, - nouveau_fence_done(fence), - timeout); - } else { - ret = wait_event_timeout(priv->waiting, - nouveau_fence_done(fence), - timeout); - } - } - - if (ret >= 0) { - fence->timeout = jiffies + ret; - if (time_after_eq(jiffies, fence->timeout)) - ret = -EBUSY; - } - } else { - if (intr) { - ret = wait_event_interruptible(priv->waiting, - nouveau_fence_done(fence)); - } else { - wait_event(priv->waiting, nouveau_fence_done(fence)); - } - } - - nouveau_event_put(pfifo->uevent, 0, &uevent.handler); - if (unlikely(ret < 0)) - return ret; - - return 0; -} - int nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr) { - struct nouveau_channel *chan = fence->channel; - struct nouveau_fence_priv *priv = chan ? chan->drm->fence : NULL; unsigned long sleep_time = NSEC_PER_MSEC / 1000; ktime_t t; int ret = 0; - while (priv && priv->uevent && lazy && !nouveau_fence_done(fence)) { - ret = nouveau_fence_wait_uevent(fence, intr); - if (ret < 0) - return ret; - } - while (!nouveau_fence_done(fence)) { if (fence->timeout && time_after_eq(jiffies, fence->timeout)) { ret = -EBUSY; @@ -213,14 +143,14 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr) int nouveau_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *chan) { - struct nouveau_fence_chan *fctx = chan->fence; + struct nouveau_fence_priv *priv = chan->drm->fence; struct nouveau_channel *prev; int ret = 0; prev = fence ? fence->channel : NULL; if (prev) { if (unlikely(prev != chan && !nouveau_fence_done(fence))) { - ret = fctx->sync(fence, prev, chan); + ret = priv->sync(fence, prev, chan); if (unlikely(ret)) ret = nouveau_fence_wait(fence, true, false); } @@ -252,8 +182,7 @@ nouveau_fence_ref(struct nouveau_fence *fence) } int -nouveau_fence_new(struct nouveau_channel *chan, bool sysmem, - struct nouveau_fence **pfence) +nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence) { struct nouveau_fence *fence; int ret = 0; @@ -264,13 +193,13 @@ nouveau_fence_new(struct nouveau_channel *chan, bool sysmem, fence = kzalloc(sizeof(*fence), GFP_KERNEL); if (!fence) return -ENOMEM; - - fence->sysmem = sysmem; kref_init(&fence->kref); - ret = nouveau_fence_emit(fence, chan); - if (ret) - nouveau_fence_unref(&fence); + if (chan) { + ret = nouveau_fence_emit(fence, chan); + if (ret) + nouveau_fence_unref(&fence); + } *pfence = fence; return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h index c89943407b52..cdb83acdffe2 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -7,15 +7,15 @@ struct nouveau_fence { struct list_head head; struct kref kref; - bool sysmem; - struct nouveau_channel *channel; unsigned long timeout; u32 sequence; + + void (*work)(void *priv, bool signalled); + void *priv; }; -int nouveau_fence_new(struct nouveau_channel *, bool sysmem, - struct nouveau_fence **); +int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); struct nouveau_fence * nouveau_fence_ref(struct nouveau_fence *); void nouveau_fence_unref(struct nouveau_fence **); @@ -29,13 +29,6 @@ struct nouveau_fence_chan { struct list_head pending; struct list_head flip; - int (*emit)(struct nouveau_fence *); - int (*sync)(struct nouveau_fence *, struct nouveau_channel *, - struct nouveau_channel *); - u32 (*read)(struct nouveau_channel *); - int (*emit32)(struct nouveau_channel *, u64, u32); - int (*sync32)(struct nouveau_channel *, u64, u32); - spinlock_t lock; u32 sequence; }; @@ -46,9 +39,10 @@ struct nouveau_fence_priv { void (*resume)(struct nouveau_drm *); int (*context_new)(struct nouveau_channel *); void (*context_del)(struct nouveau_channel *); - - wait_queue_head_t waiting; - bool uevent; + int (*emit)(struct nouveau_fence *); + int (*sync)(struct nouveau_fence *, struct nouveau_channel *, + struct nouveau_channel *); + u32 (*read)(struct nouveau_channel *); }; #define nouveau_fence(drm) ((struct nouveau_fence_priv *)(drm)->fence) @@ -66,31 +60,13 @@ u32 nv10_fence_read(struct nouveau_channel *); void nv10_fence_context_del(struct nouveau_channel *); void nv10_fence_destroy(struct nouveau_drm *); int nv10_fence_create(struct nouveau_drm *); - -int nv17_fence_create(struct nouveau_drm *); void nv17_fence_resume(struct nouveau_drm *drm); int nv50_fence_create(struct nouveau_drm *); int nv84_fence_create(struct nouveau_drm *); int nvc0_fence_create(struct nouveau_drm *); +u64 nvc0_fence_crtc(struct nouveau_channel *, int crtc); int nouveau_flip_complete(void *chan); -struct nv84_fence_chan { - struct nouveau_fence_chan base; - struct nouveau_vma vma; - struct nouveau_vma vma_gart; - struct nouveau_vma dispc_vma[4]; -}; - -struct nv84_fence_priv { - struct nouveau_fence_priv base; - struct nouveau_bo *bo; - struct nouveau_bo *bo_gart; - u32 *suspend; -}; - -u64 nv84_fence_crtc(struct nouveau_channel *, int); -int nv84_fence_context_new(struct nouveau_channel *); - #endif diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c index b4b4d0c1f4af..d98bee012cab 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -203,7 +203,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_fb *pfb = nouveau_fb(drm->device); struct drm_nouveau_gem_new *req = data; struct nouveau_bo *nvbo = NULL; @@ -212,7 +211,7 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, drm->ttm.bdev.dev_mapping = drm->dev->dev_mapping; if (!pfb->memtype_valid(pfb, req->info.tile_flags)) { - NV_ERROR(cli, "bad page flags: 0x%08x\n", req->info.tile_flags); + NV_ERROR(drm, "bad page flags: 0x%08x\n", req->info.tile_flags); return -EINVAL; } @@ -314,7 +313,6 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, struct drm_nouveau_gem_pushbuf_bo *pbbo, int nr_buffers, struct validate_op *op) { - struct nouveau_cli *cli = nouveau_cli(file_priv); struct drm_device *dev = chan->drm->dev; struct nouveau_drm *drm = nouveau_drm(dev); uint32_t sequence; @@ -325,7 +323,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, sequence = atomic_add_return(1, &drm->ttm.validate_sequence); retry: if (++trycnt > 100000) { - NV_ERROR(cli, "%s failed and gave up.\n", __func__); + NV_ERROR(drm, "%s failed and gave up.\n", __func__); return -EINVAL; } @@ -336,7 +334,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, gem = drm_gem_object_lookup(dev, file_priv, b->handle); if (!gem) { - NV_ERROR(cli, "Unknown handle 0x%08x\n", b->handle); + NV_ERROR(drm, "Unknown handle 0x%08x\n", b->handle); validate_fini(op, NULL); return -ENOENT; } @@ -348,7 +346,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, } if (nvbo->reserved_by && nvbo->reserved_by == file_priv) { - NV_ERROR(cli, "multiple instances of buffer %d on " + NV_ERROR(drm, "multiple instances of buffer %d on " "validation list\n", b->handle); drm_gem_object_unreference_unlocked(gem); validate_fini(op, NULL); @@ -368,7 +366,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, if (unlikely(ret)) { drm_gem_object_unreference_unlocked(gem); if (ret != -ERESTARTSYS) - NV_ERROR(cli, "fail reserve\n"); + NV_ERROR(drm, "fail reserve\n"); return ret; } } @@ -386,7 +384,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, if (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART) list_add_tail(&nvbo->entry, &op->gart_list); else { - NV_ERROR(cli, "invalid valid domains: 0x%08x\n", + NV_ERROR(drm, "invalid valid domains: 0x%08x\n", b->valid_domains); list_add_tail(&nvbo->entry, &op->both_list); validate_fini(op, NULL); @@ -419,9 +417,8 @@ validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) } static int -validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, - struct list_head *list, struct drm_nouveau_gem_pushbuf_bo *pbbo, - uint64_t user_pbbo_ptr) +validate_list(struct nouveau_channel *chan, struct list_head *list, + struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) { struct nouveau_drm *drm = chan->drm; struct drm_nouveau_gem_pushbuf_bo __user *upbbo = @@ -434,7 +431,7 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, ret = validate_sync(chan, nvbo); if (unlikely(ret)) { - NV_ERROR(cli, "fail pre-validate sync\n"); + NV_ERROR(drm, "fail pre-validate sync\n"); return ret; } @@ -442,20 +439,20 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, b->write_domains, b->valid_domains); if (unlikely(ret)) { - NV_ERROR(cli, "fail set_domain\n"); + NV_ERROR(drm, "fail set_domain\n"); return ret; } ret = nouveau_bo_validate(nvbo, true, false); if (unlikely(ret)) { if (ret != -ERESTARTSYS) - NV_ERROR(cli, "fail ttm_validate\n"); + NV_ERROR(drm, "fail ttm_validate\n"); return ret; } ret = validate_sync(chan, nvbo); if (unlikely(ret)) { - NV_ERROR(cli, "fail post-validate sync\n"); + NV_ERROR(drm, "fail post-validate sync\n"); return ret; } @@ -491,7 +488,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, uint64_t user_buffers, int nr_buffers, struct validate_op *op, int *apply_relocs) { - struct nouveau_cli *cli = nouveau_cli(file_priv); + struct nouveau_drm *drm = chan->drm; int ret, relocs = 0; INIT_LIST_HEAD(&op->vram_list); @@ -504,32 +501,32 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ret = validate_init(chan, file_priv, pbbo, nr_buffers, op); if (unlikely(ret)) { if (ret != -ERESTARTSYS) - NV_ERROR(cli, "validate_init\n"); + NV_ERROR(drm, "validate_init\n"); return ret; } - ret = validate_list(chan, cli, &op->vram_list, pbbo, user_buffers); + ret = validate_list(chan, &op->vram_list, pbbo, user_buffers); if (unlikely(ret < 0)) { if (ret != -ERESTARTSYS) - NV_ERROR(cli, "validate vram_list\n"); + NV_ERROR(drm, "validate vram_list\n"); validate_fini(op, NULL); return ret; } relocs += ret; - ret = validate_list(chan, cli, &op->gart_list, pbbo, user_buffers); + ret = validate_list(chan, &op->gart_list, pbbo, user_buffers); if (unlikely(ret < 0)) { if (ret != -ERESTARTSYS) - NV_ERROR(cli, "validate gart_list\n"); + NV_ERROR(drm, "validate gart_list\n"); validate_fini(op, NULL); return ret; } relocs += ret; - ret = validate_list(chan, cli, &op->both_list, pbbo, user_buffers); + ret = validate_list(chan, &op->both_list, pbbo, user_buffers); if (unlikely(ret < 0)) { if (ret != -ERESTARTSYS) - NV_ERROR(cli, "validate both_list\n"); + NV_ERROR(drm, "validate both_list\n"); validate_fini(op, NULL); return ret; } @@ -558,10 +555,11 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) } static int -nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, +nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev, struct drm_nouveau_gem_pushbuf *req, struct drm_nouveau_gem_pushbuf_bo *bo) { + struct nouveau_drm *drm = nouveau_drm(dev); struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL; int ret = 0; unsigned i; @@ -577,7 +575,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, uint32_t data; if (unlikely(r->bo_index > req->nr_buffers)) { - NV_ERROR(cli, "reloc bo index invalid\n"); + NV_ERROR(drm, "reloc bo index invalid\n"); ret = -EINVAL; break; } @@ -587,7 +585,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, continue; if (unlikely(r->reloc_bo_index > req->nr_buffers)) { - NV_ERROR(cli, "reloc container bo index invalid\n"); + NV_ERROR(drm, "reloc container bo index invalid\n"); ret = -EINVAL; break; } @@ -595,7 +593,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, if (unlikely(r->reloc_bo_offset + 4 > nvbo->bo.mem.num_pages << PAGE_SHIFT)) { - NV_ERROR(cli, "reloc outside of bo\n"); + NV_ERROR(drm, "reloc outside of bo\n"); ret = -EINVAL; break; } @@ -604,7 +602,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, &nvbo->kmap); if (ret) { - NV_ERROR(cli, "failed kmap for reloc\n"); + NV_ERROR(drm, "failed kmap for reloc\n"); break; } nvbo->validate_mapped = true; @@ -629,7 +627,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, ret = ttm_bo_wait(&nvbo->bo, false, false, false); spin_unlock(&nvbo->bo.bdev->fence_lock); if (ret) { - NV_ERROR(cli, "reloc wait_idle failed: %d\n", ret); + NV_ERROR(drm, "reloc wait_idle failed: %d\n", ret); break; } @@ -645,7 +643,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); - struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_abi16_chan *temp; struct nouveau_drm *drm = nouveau_drm(dev); struct drm_nouveau_gem_pushbuf *req = data; @@ -675,19 +672,19 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, goto out_next; if (unlikely(req->nr_push > NOUVEAU_GEM_MAX_PUSH)) { - NV_ERROR(cli, "pushbuf push count exceeds limit: %d max %d\n", + NV_ERROR(drm, "pushbuf push count exceeds limit: %d max %d\n", req->nr_push, NOUVEAU_GEM_MAX_PUSH); return nouveau_abi16_put(abi16, -EINVAL); } if (unlikely(req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS)) { - NV_ERROR(cli, "pushbuf bo count exceeds limit: %d max %d\n", + NV_ERROR(drm, "pushbuf bo count exceeds limit: %d max %d\n", req->nr_buffers, NOUVEAU_GEM_MAX_BUFFERS); return nouveau_abi16_put(abi16, -EINVAL); } if (unlikely(req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS)) { - NV_ERROR(cli, "pushbuf reloc count exceeds limit: %d max %d\n", + NV_ERROR(drm, "pushbuf reloc count exceeds limit: %d max %d\n", req->nr_relocs, NOUVEAU_GEM_MAX_RELOCS); return nouveau_abi16_put(abi16, -EINVAL); } @@ -705,7 +702,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, /* Ensure all push buffers are on validate list */ for (i = 0; i < req->nr_push; i++) { if (push[i].bo_index >= req->nr_buffers) { - NV_ERROR(cli, "push %d buffer not in list\n", i); + NV_ERROR(drm, "push %d buffer not in list\n", i); ret = -EINVAL; goto out_prevalid; } @@ -716,15 +713,15 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, req->nr_buffers, &op, &do_reloc); if (ret) { if (ret != -ERESTARTSYS) - NV_ERROR(cli, "validate: %d\n", ret); + NV_ERROR(drm, "validate: %d\n", ret); goto out_prevalid; } /* Apply any relocations that are required */ if (do_reloc) { - ret = nouveau_gem_pushbuf_reloc_apply(cli, req, bo); + ret = nouveau_gem_pushbuf_reloc_apply(dev, req, bo); if (ret) { - NV_ERROR(cli, "reloc apply: %d\n", ret); + NV_ERROR(drm, "reloc apply: %d\n", ret); goto out; } } @@ -732,7 +729,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, if (chan->dma.ib_max) { ret = nouveau_dma_wait(chan, req->nr_push + 1, 16); if (ret) { - NV_ERROR(cli, "nv50cal_space: %d\n", ret); + NV_ERROR(drm, "nv50cal_space: %d\n", ret); goto out; } @@ -747,7 +744,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, if (nv_device(drm->device)->chipset >= 0x25) { ret = RING_SPACE(chan, req->nr_push * 2); if (ret) { - NV_ERROR(cli, "cal_space: %d\n", ret); + NV_ERROR(drm, "cal_space: %d\n", ret); goto out; } @@ -761,7 +758,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, } else { ret = RING_SPACE(chan, req->nr_push * (2 + NOUVEAU_DMA_SKIPS)); if (ret) { - NV_ERROR(cli, "jmp_space: %d\n", ret); + NV_ERROR(drm, "jmp_space: %d\n", ret); goto out; } @@ -797,9 +794,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, } } - ret = nouveau_fence_new(chan, false, &fence); + ret = nouveau_fence_new(chan, &fence); if (ret) { - NV_ERROR(cli, "error fencing pushbuf: %d\n", ret); + NV_ERROR(drm, "error fencing pushbuf: %d\n", ret); WIND_RING(chan); goto out; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c index bb54098c6d97..a701ff5ffa5b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -408,81 +408,6 @@ nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp, NULL, 0); -static ssize_t -nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d, - struct device_attribute *a, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", 100); -} -static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO, - nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0); - -static ssize_t -nouveau_hwmon_temp1_auto_point1_temp(struct device *d, - struct device_attribute *a, char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - - return snprintf(buf, PAGE_SIZE, "%d\n", - therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST) * 1000); -} -static ssize_t -nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d, - struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST, - value / 1000); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR, - nouveau_hwmon_temp1_auto_point1_temp, - nouveau_hwmon_set_temp1_auto_point1_temp, 0); - -static ssize_t -nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d, - struct device_attribute *a, char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - - return snprintf(buf, PAGE_SIZE, "%d\n", - therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000); -} -static ssize_t -nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d, - struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST, - value / 1000); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR, - nouveau_hwmon_temp1_auto_point1_temp_hyst, - nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0); - static ssize_t nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf) { @@ -513,38 +438,6 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp, nouveau_hwmon_set_max_temp, 0); -static ssize_t -nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a, - char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - - return snprintf(buf, PAGE_SIZE, "%d\n", - therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000); -} -static ssize_t -nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST, - value / 1000); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, - nouveau_hwmon_max_temp_hyst, - nouveau_hwmon_set_max_temp_hyst, 0); - static ssize_t nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a, char *buf) @@ -578,107 +471,6 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, nouveau_hwmon_set_critical_temp, 0); -static ssize_t -nouveau_hwmon_critical_temp_hyst(struct device *d, struct device_attribute *a, - char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - - return snprintf(buf, PAGE_SIZE, "%d\n", - therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST) * 1000); -} -static ssize_t -nouveau_hwmon_set_critical_temp_hyst(struct device *d, - struct device_attribute *a, - const char *buf, - size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST, - value / 1000); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR, - nouveau_hwmon_critical_temp_hyst, - nouveau_hwmon_set_critical_temp_hyst, 0); -static ssize_t -nouveau_hwmon_emergency_temp(struct device *d, struct device_attribute *a, - char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - - return snprintf(buf, PAGE_SIZE, "%d\n", - therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN) * 1000); -} -static ssize_t -nouveau_hwmon_set_emergency_temp(struct device *d, struct device_attribute *a, - const char *buf, - size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN, value / 1000); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_emergency, S_IRUGO | S_IWUSR, - nouveau_hwmon_emergency_temp, - nouveau_hwmon_set_emergency_temp, - 0); - -static ssize_t -nouveau_hwmon_emergency_temp_hyst(struct device *d, struct device_attribute *a, - char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - - return snprintf(buf, PAGE_SIZE, "%d\n", - therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST) * 1000); -} -static ssize_t -nouveau_hwmon_set_emergency_temp_hyst(struct device *d, - struct device_attribute *a, - const char *buf, - size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_therm *therm = nouveau_therm(drm->device); - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST, - value / 1000); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO | S_IWUSR, - nouveau_hwmon_emergency_temp_hyst, - nouveau_hwmon_set_emergency_temp_hyst, - 0); - static ssize_t nouveau_hwmon_show_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -698,7 +490,7 @@ static SENSOR_DEVICE_ATTR(update_rate, S_IRUGO, NULL, 0); static ssize_t -nouveau_hwmon_show_fan1_input(struct device *d, struct device_attribute *attr, +nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr, char *buf) { struct drm_device *dev = dev_get_drvdata(d); @@ -707,7 +499,7 @@ nouveau_hwmon_show_fan1_input(struct device *d, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%d\n", therm->fan_sense(therm)); } -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, nouveau_hwmon_show_fan1_input, +static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input, NULL, 0); static ssize_t @@ -873,21 +665,14 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR, static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr, - &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, - &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, - &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_emergency.dev_attr.attr, - &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr, &sensor_dev_attr_name.dev_attr.attr, &sensor_dev_attr_update_rate.dev_attr.attr, NULL }; static struct attribute *hwmon_fan_rpm_attributes[] = { - &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan0_input.dev_attr.attr, NULL }; static struct attribute *hwmon_pwm_fan_attributes[] = { @@ -932,7 +717,7 @@ nouveau_hwmon_init(struct drm_device *dev) dev_set_drvdata(hwmon_dev, dev); /* default sysfs entries */ - ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_attrgroup); + ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_attrgroup); if (ret) { if (ret) goto error; @@ -943,7 +728,7 @@ nouveau_hwmon_init(struct drm_device *dev) * the gpio entries for pwm fan control even when there's no * actual fan connected to it... therm table? */ if (therm->fan_get && therm->fan_get(therm) >= 0) { - ret = sysfs_create_group(&hwmon_dev->kobj, + ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_pwm_fan_attrgroup); if (ret) goto error; @@ -951,7 +736,7 @@ nouveau_hwmon_init(struct drm_device *dev) /* if the card can read the fan rpm */ if (therm->fan_sense(therm) >= 0) { - ret = sysfs_create_group(&hwmon_dev->kobj, + ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_fan_rpm_attrgroup); if (ret) goto error; @@ -979,10 +764,10 @@ nouveau_hwmon_fini(struct drm_device *dev) struct nouveau_pm *pm = nouveau_pm(dev); if (pm->hwmon) { - sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup); - sysfs_remove_group(&pm->hwmon->kobj, + sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_attrgroup); + sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_pwm_fan_attrgroup); - sysfs_remove_group(&pm->hwmon->kobj, + sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_fan_rpm_attrgroup); hwmon_device_unregister(pm->hwmon); diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c index 7e24cdf1cb39..39ffc07f906b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -490,8 +490,8 @@ 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->pci_device == 0x0174 || dev->pci_device == 0x0179 || - dev->pci_device == 0x0189 || dev->pci_device == 0x0329) { + if (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, 0, 1 << 31); nv_mask(device, NV_PCRTC_GPIO_EXT, 3, 1); diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_display.c b/trunk/drivers/gpu/drm/nouveau/nv04_display.c index ad48444c385c..4c6e9f83fe82 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_display.c @@ -22,9 +22,6 @@ * Author: Ben Skeggs */ -#include -#include - #include #include @@ -34,8 +31,6 @@ #include "nouveau_encoder.h" #include "nouveau_connector.h" -#include - int nv04_display_early_init(struct drm_device *dev) { @@ -58,7 +53,6 @@ int nv04_display_create(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct dcb_table *dcb = &drm->vbios.dcb; struct drm_connector *connector, *ct; struct drm_encoder *encoder; @@ -77,11 +71,6 @@ nv04_display_create(struct drm_device *dev) nouveau_hw_save_vga_fonts(dev, 1); - ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, 0xd1500000, - NV04_DISP_CLASS, NULL, 0, &disp->core); - if (ret) - return ret; - nv04_crtc_create(dev, 0); if (nv_two_heads(dev)) nv04_crtc_create(dev, 1); @@ -125,11 +114,6 @@ nv04_display_create(struct drm_device *dev) } } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - nv_encoder->i2c = i2c->find(i2c, nv_encoder->dcb->i2c_index); - } - /* Save previous state */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->save(crtc); diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_display.h b/trunk/drivers/gpu/drm/nouveau/nv04_display.h index a0a031dad13f..45322802e37d 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_display.h +++ b/trunk/drivers/gpu/drm/nouveau/nv04_display.h @@ -80,7 +80,6 @@ struct nv04_display { struct nv04_mode_state saved_reg; uint32_t saved_vga_font[4][16384]; uint32_t dac_users[4]; - struct nouveau_object *core; }; static inline struct nv04_display * diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_fence.c b/trunk/drivers/gpu/drm/nouveau/nv04_fence.c index 94eadd1dd10a..a220b94ba9f2 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_fence.c @@ -78,9 +78,6 @@ nv04_fence_context_new(struct nouveau_channel *chan) struct nv04_fence_chan *fctx = kzalloc(sizeof(*fctx), GFP_KERNEL); if (fctx) { nouveau_fence_context_new(&fctx->base); - fctx->base.emit = nv04_fence_emit; - fctx->base.sync = nv04_fence_sync; - fctx->base.read = nv04_fence_read; chan->fence = fctx; return 0; } @@ -107,5 +104,8 @@ nv04_fence_create(struct nouveau_drm *drm) priv->base.dtor = nv04_fence_destroy; priv->base.context_new = nv04_fence_context_new; priv->base.context_del = nv04_fence_context_del; + priv->base.emit = nv04_fence_emit; + priv->base.sync = nv04_fence_sync; + priv->base.read = nv04_fence_read; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/nv10_fence.c b/trunk/drivers/gpu/drm/nouveau/nv10_fence.c index 06f434f03fba..03017f24d593 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv10_fence.c @@ -27,7 +27,18 @@ #include "nouveau_drm.h" #include "nouveau_dma.h" -#include "nv10_fence.h" +#include "nouveau_fence.h" + +struct nv10_fence_chan { + struct nouveau_fence_chan base; +}; + +struct nv10_fence_priv { + struct nouveau_fence_priv base; + struct nouveau_bo *bo; + spinlock_t lock; + u32 sequence; +}; int nv10_fence_emit(struct nouveau_fence *fence) @@ -50,6 +61,45 @@ nv10_fence_sync(struct nouveau_fence *fence, return -ENODEV; } +int +nv17_fence_sync(struct nouveau_fence *fence, + struct nouveau_channel *prev, struct nouveau_channel *chan) +{ + struct nv10_fence_priv *priv = chan->drm->fence; + u32 value; + int ret; + + if (!mutex_trylock(&prev->cli->mutex)) + return -EBUSY; + + spin_lock(&priv->lock); + value = priv->sequence; + priv->sequence += 2; + spin_unlock(&priv->lock); + + ret = RING_SPACE(prev, 5); + if (!ret) { + BEGIN_NV04(prev, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); + OUT_RING (prev, NvSema); + OUT_RING (prev, 0); + OUT_RING (prev, value + 0); + OUT_RING (prev, value + 1); + FIRE_RING (prev); + } + + if (!ret && !(ret = RING_SPACE(chan, 5))) { + BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); + OUT_RING (chan, NvSema); + OUT_RING (chan, 0); + OUT_RING (chan, value + 1); + OUT_RING (chan, value + 2); + FIRE_RING (chan); + } + + mutex_unlock(&prev->cli->mutex); + return 0; +} + u32 nv10_fence_read(struct nouveau_channel *chan) { @@ -65,20 +115,39 @@ nv10_fence_context_del(struct nouveau_channel *chan) kfree(fctx); } -int +static int nv10_fence_context_new(struct nouveau_channel *chan) { + struct nv10_fence_priv *priv = chan->drm->fence; struct nv10_fence_chan *fctx; + int ret = 0; fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); if (!fctx) return -ENOMEM; nouveau_fence_context_new(&fctx->base); - fctx->base.emit = nv10_fence_emit; - fctx->base.read = nv10_fence_read; - fctx->base.sync = nv10_fence_sync; - return 0; + + if (priv->bo) { + struct ttm_mem_reg *mem = &priv->bo->bo.mem; + struct nouveau_object *object; + u32 start = mem->start * PAGE_SIZE; + u32 limit = mem->start + mem->size - 1; + + ret = nouveau_object_new(nv_object(chan->cli), chan->handle, + NvSema, 0x0002, + &(struct nv_dma_class) { + .flags = NV_DMA_TARGET_VRAM | + NV_DMA_ACCESS_RDWR, + .start = start, + .limit = limit, + }, sizeof(struct nv_dma_class), + &object); + } + + if (ret) + nv10_fence_context_del(chan); + return ret; } void @@ -93,10 +162,18 @@ nv10_fence_destroy(struct nouveau_drm *drm) kfree(priv); } +void nv17_fence_resume(struct nouveau_drm *drm) +{ + struct nv10_fence_priv *priv = drm->fence; + + nouveau_bo_wr32(priv->bo, 0, priv->sequence); +} + int nv10_fence_create(struct nouveau_drm *drm) { struct nv10_fence_priv *priv; + int ret = 0; priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) @@ -105,6 +182,33 @@ nv10_fence_create(struct nouveau_drm *drm) priv->base.dtor = nv10_fence_destroy; priv->base.context_new = nv10_fence_context_new; priv->base.context_del = nv10_fence_context_del; + priv->base.emit = nv10_fence_emit; + priv->base.read = nv10_fence_read; + priv->base.sync = nv10_fence_sync; spin_lock_init(&priv->lock); - return 0; + + if (nv_device(drm->device)->chipset >= 0x17) { + ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, + 0, 0x0000, NULL, &priv->bo); + if (!ret) { + ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); + if (!ret) { + ret = nouveau_bo_map(priv->bo); + if (ret) + nouveau_bo_unpin(priv->bo); + } + if (ret) + nouveau_bo_ref(NULL, &priv->bo); + } + + if (ret == 0) { + nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); + priv->base.sync = nv17_fence_sync; + priv->base.resume = nv17_fence_resume; + } + } + + if (ret) + nv10_fence_destroy(drm); + return ret; } diff --git a/trunk/drivers/gpu/drm/nouveau/nv10_fence.h b/trunk/drivers/gpu/drm/nouveau/nv10_fence.h deleted file mode 100644 index e5d9204826c2..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/nv10_fence.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __NV10_FENCE_H_ -#define __NV10_FENCE_H_ - -#include -#include "nouveau_fence.h" -#include "nouveau_bo.h" - -struct nv10_fence_chan { - struct nouveau_fence_chan base; -}; - -struct nv10_fence_priv { - struct nouveau_fence_priv base; - struct nouveau_bo *bo; - spinlock_t lock; - u32 sequence; -}; - -#endif diff --git a/trunk/drivers/gpu/drm/nouveau/nv17_fence.c b/trunk/drivers/gpu/drm/nouveau/nv17_fence.c deleted file mode 100644 index 8e47a9bae8c3..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/nv17_fence.c +++ /dev/null @@ -1,149 +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 -#include - -#include "nouveau_drm.h" -#include "nouveau_dma.h" -#include "nv10_fence.h" - -int -nv17_fence_sync(struct nouveau_fence *fence, - struct nouveau_channel *prev, struct nouveau_channel *chan) -{ - struct nv10_fence_priv *priv = chan->drm->fence; - u32 value; - int ret; - - if (!mutex_trylock(&prev->cli->mutex)) - return -EBUSY; - - spin_lock(&priv->lock); - value = priv->sequence; - priv->sequence += 2; - spin_unlock(&priv->lock); - - ret = RING_SPACE(prev, 5); - if (!ret) { - BEGIN_NV04(prev, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); - OUT_RING (prev, NvSema); - OUT_RING (prev, 0); - OUT_RING (prev, value + 0); - OUT_RING (prev, value + 1); - FIRE_RING (prev); - } - - if (!ret && !(ret = RING_SPACE(chan, 5))) { - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); - OUT_RING (chan, NvSema); - OUT_RING (chan, 0); - OUT_RING (chan, value + 1); - OUT_RING (chan, value + 2); - FIRE_RING (chan); - } - - mutex_unlock(&prev->cli->mutex); - return 0; -} - -static int -nv17_fence_context_new(struct nouveau_channel *chan) -{ - struct nv10_fence_priv *priv = chan->drm->fence; - struct nv10_fence_chan *fctx; - struct ttm_mem_reg *mem = &priv->bo->bo.mem; - struct nouveau_object *object; - u32 start = mem->start * PAGE_SIZE; - u32 limit = mem->start + mem->size - 1; - int ret = 0; - - fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); - if (!fctx) - return -ENOMEM; - - nouveau_fence_context_new(&fctx->base); - fctx->base.emit = nv10_fence_emit; - fctx->base.read = nv10_fence_read; - fctx->base.sync = nv17_fence_sync; - - ret = nouveau_object_new(nv_object(chan->cli), chan->handle, - NvSema, 0x0002, - &(struct nv_dma_class) { - .flags = NV_DMA_TARGET_VRAM | - NV_DMA_ACCESS_RDWR, - .start = start, - .limit = limit, - }, sizeof(struct nv_dma_class), - &object); - if (ret) - nv10_fence_context_del(chan); - return ret; -} - -void -nv17_fence_resume(struct nouveau_drm *drm) -{ - struct nv10_fence_priv *priv = drm->fence; - - nouveau_bo_wr32(priv->bo, 0, priv->sequence); -} - -int -nv17_fence_create(struct nouveau_drm *drm) -{ - struct nv10_fence_priv *priv; - int ret = 0; - - priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->base.dtor = nv10_fence_destroy; - priv->base.resume = nv17_fence_resume; - priv->base.context_new = nv17_fence_context_new; - priv->base.context_del = nv10_fence_context_del; - spin_lock_init(&priv->lock); - - ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, - 0, 0x0000, NULL, &priv->bo); - if (!ret) { - ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); - if (!ret) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_ref(NULL, &priv->bo); - } - - if (ret) { - nv10_fence_destroy(drm); - return ret; - } - - nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); - return ret; -} diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_display.c b/trunk/drivers/gpu/drm/nouveau/nv50_display.c index a6237c9cbbc3..d4cbea19b890 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_display.c @@ -43,7 +43,6 @@ #include #include #include -#include #define EVO_DMA_NR 9 @@ -434,10 +433,7 @@ evo_kick(u32 *push, void *evoc) static bool evo_sync_wait(void *data) { - if (nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000) - return true; - usleep_range(1, 2); - return false; + return nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000; } static int @@ -516,7 +512,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, if (ret) return ret; - if (nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { + if (nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); OUT_RING (chan, NvEvoSema0 + nv_crtc->index); OUT_RING (chan, sync->sem.offset); @@ -526,36 +522,24 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, OUT_RING (chan, sync->sem.offset ^ 0x10); OUT_RING (chan, 0x74b1e000); BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, NvSema); - } else - if (nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { - u64 offset = nv84_fence_crtc(chan, nv_crtc->index); - offset += sync->sem.offset; - - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 0xf00d0000 | sync->sem.value); - OUT_RING (chan, 0x00000002); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset ^ 0x10)); - OUT_RING (chan, 0x74b1e000); - OUT_RING (chan, 0x00000001); + if (nv_mclass(chan->object) < NV84_CHANNEL_DMA_CLASS) + OUT_RING (chan, NvSema); + else + OUT_RING (chan, chan->vram); } else { - u64 offset = nv84_fence_crtc(chan, nv_crtc->index); + u64 offset = nvc0_fence_crtc(chan, nv_crtc->index); offset += sync->sem.offset; BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); OUT_RING (chan, upper_32_bits(offset)); OUT_RING (chan, lower_32_bits(offset)); OUT_RING (chan, 0xf00d0000 | sync->sem.value); - OUT_RING (chan, 0x00001002); + OUT_RING (chan, 0x1002); BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); OUT_RING (chan, upper_32_bits(offset)); OUT_RING (chan, lower_32_bits(offset ^ 0x10)); OUT_RING (chan, 0x74b1e000); - OUT_RING (chan, 0x00001001); + OUT_RING (chan, 0x1001); } FIRE_RING (chan); @@ -1519,6 +1503,9 @@ nv50_dac_disconnect(struct drm_encoder *encoder) evo_mthd(push, 0x0180 + (or * 0x020), 1); evo_data(push, 0x00000000); } + + evo_mthd(push, 0x0080, 1); + evo_data(push, 0x00000000); evo_kick(push, mast); } } @@ -1565,23 +1552,20 @@ static const struct drm_encoder_funcs nv50_dac_func = { static int nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe) { - struct nouveau_drm *drm = nouveau_drm(connector->dev); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); + struct drm_device *dev = connector->dev; struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; - int type = DRM_MODE_ENCODER_DAC; nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) return -ENOMEM; nv_encoder->dcb = dcbe; nv_encoder->or = ffs(dcbe->or) - 1; - nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index); encoder = to_drm_encoder(nv_encoder); encoder->possible_crtcs = dcbe->heads; encoder->possible_clones = 0; - drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type); + drm_encoder_init(dev, encoder, &nv50_dac_func, DRM_MODE_ENCODER_DAC); drm_encoder_helper_add(encoder, &nv50_dac_hfunc); drm_mode_connector_attach_encoder(connector, encoder); @@ -1690,6 +1674,9 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) } nv_call(disp->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); + + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) + nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, disp->core); } static bool @@ -1732,6 +1719,9 @@ nv50_sor_disconnect(struct drm_encoder *encoder) evo_mthd(push, 0x0200 + (or * 0x20), 1); evo_data(push, 0x00000000); } + + evo_mthd(push, 0x0080, 1); + evo_data(push, 0x00000000); evo_kick(push, mast); } @@ -1742,6 +1732,14 @@ nv50_sor_disconnect(struct drm_encoder *encoder) nv_encoder->crtc = NULL; } +static void +nv50_sor_prepare(struct drm_encoder *encoder) +{ + nv50_sor_disconnect(encoder); + if (nouveau_encoder(encoder)->dcb->type == DCB_OUTPUT_DP) + evo_sync(encoder->dev); +} + static void nv50_sor_commit(struct drm_encoder *encoder) { @@ -1837,13 +1835,8 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, push = evo_wait(nv50_mast(dev), 8); if (push) { if (nv50_vers(mast) < NVD0_DISP_CLASS) { - u32 ctrl = (depth << 16) | (proto << 8) | owner; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - ctrl |= 0x00001000; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - ctrl |= 0x00002000; evo_mthd(push, 0x0600 + (nv_encoder->or * 0x040), 1); - evo_data(push, ctrl); + evo_data(push, (depth << 16) | (proto << 8) | owner); } else { u32 magic = 0x31ec6000 | (nv_crtc->index << 25); u32 syncs = 0x00000001; @@ -1879,7 +1872,7 @@ nv50_sor_destroy(struct drm_encoder *encoder) static const struct drm_encoder_helper_funcs nv50_sor_hfunc = { .dpms = nv50_sor_dpms, .mode_fixup = nv50_sor_mode_fixup, - .prepare = nv50_sor_disconnect, + .prepare = nv50_sor_prepare, .commit = nv50_sor_commit, .mode_set = nv50_sor_mode_set, .disable = nv50_sor_disconnect, @@ -1893,214 +1886,27 @@ static const struct drm_encoder_funcs nv50_sor_func = { static int nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) { - struct nouveau_drm *drm = nouveau_drm(connector->dev); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); + struct drm_device *dev = connector->dev; struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; - int type; - - switch (dcbe->type) { - case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break; - case DCB_OUTPUT_TMDS: - case DCB_OUTPUT_DP: - default: - type = DRM_MODE_ENCODER_TMDS; - break; - } nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) return -ENOMEM; nv_encoder->dcb = dcbe; nv_encoder->or = ffs(dcbe->or) - 1; - nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index); nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; encoder = to_drm_encoder(nv_encoder); encoder->possible_crtcs = dcbe->heads; encoder->possible_clones = 0; - drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type); + drm_encoder_init(dev, encoder, &nv50_sor_func, DRM_MODE_ENCODER_TMDS); drm_encoder_helper_add(encoder, &nv50_sor_hfunc); drm_mode_connector_attach_encoder(connector, encoder); return 0; } -/****************************************************************************** - * PIOR - *****************************************************************************/ - -static void -nv50_pior_dpms(struct drm_encoder *encoder, int mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nv50_disp *disp = nv50_disp(encoder->dev); - u32 mthd = (nv_encoder->dcb->type << 12) | nv_encoder->or; - u32 ctrl = (mode == DRM_MODE_DPMS_ON); - nv_call(disp->core, NV50_DISP_PIOR_PWR + mthd, ctrl); -} - -static bool -nv50_pior_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *nv_connector; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (nv_connector && nv_connector->native_mode) { - if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) { - int id = adjusted_mode->base.id; - *adjusted_mode = *nv_connector->native_mode; - adjusted_mode->base.id = id; - } - } - - adjusted_mode->clock *= 2; - return true; -} - -static void -nv50_pior_commit(struct drm_encoder *encoder) -{ -} - -static void -nv50_pior_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nv50_mast *mast = nv50_mast(encoder->dev); - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nouveau_connector *nv_connector; - u8 owner = 1 << nv_crtc->index; - u8 proto, depth; - u32 *push; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - switch (nv_connector->base.display_info.bpc) { - case 10: depth = 0x6; break; - case 8: depth = 0x5; break; - case 6: depth = 0x2; break; - default: depth = 0x0; break; - } - - switch (nv_encoder->dcb->type) { - case DCB_OUTPUT_TMDS: - case DCB_OUTPUT_DP: - proto = 0x0; - break; - default: - BUG_ON(1); - break; - } - - nv50_pior_dpms(encoder, DRM_MODE_DPMS_ON); - - push = evo_wait(mast, 8); - if (push) { - if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) { - u32 ctrl = (depth << 16) | (proto << 8) | owner; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - ctrl |= 0x00001000; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - ctrl |= 0x00002000; - evo_mthd(push, 0x0700 + (nv_encoder->or * 0x040), 1); - evo_data(push, ctrl); - } - - evo_kick(push, mast); - } - - nv_encoder->crtc = encoder->crtc; -} - -static void -nv50_pior_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nv50_mast *mast = nv50_mast(encoder->dev); - const int or = nv_encoder->or; - u32 *push; - - if (nv_encoder->crtc) { - nv50_crtc_prepare(nv_encoder->crtc); - - push = evo_wait(mast, 4); - if (push) { - if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) { - evo_mthd(push, 0x0700 + (or * 0x040), 1); - evo_data(push, 0x00000000); - } - evo_kick(push, mast); - } - } - - nv_encoder->crtc = NULL; -} - -static void -nv50_pior_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); - kfree(encoder); -} - -static const struct drm_encoder_helper_funcs nv50_pior_hfunc = { - .dpms = nv50_pior_dpms, - .mode_fixup = nv50_pior_mode_fixup, - .prepare = nv50_pior_disconnect, - .commit = nv50_pior_commit, - .mode_set = nv50_pior_mode_set, - .disable = nv50_pior_disconnect, - .get_crtc = nv50_display_crtc_get, -}; - -static const struct drm_encoder_funcs nv50_pior_func = { - .destroy = nv50_pior_destroy, -}; - -static int -nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) -{ - struct nouveau_drm *drm = nouveau_drm(connector->dev); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); - struct nouveau_i2c_port *ddc = NULL; - struct nouveau_encoder *nv_encoder; - struct drm_encoder *encoder; - int type; - - switch (dcbe->type) { - case DCB_OUTPUT_TMDS: - ddc = i2c->find_type(i2c, NV_I2C_TYPE_EXTDDC(dcbe->extdev)); - type = DRM_MODE_ENCODER_TMDS; - break; - case DCB_OUTPUT_DP: - ddc = i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(dcbe->extdev)); - type = DRM_MODE_ENCODER_TMDS; - break; - default: - return -ENODEV; - } - - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - nv_encoder->dcb = dcbe; - nv_encoder->or = ffs(dcbe->or) - 1; - nv_encoder->i2c = ddc; - - encoder = to_drm_encoder(nv_encoder); - encoder->possible_crtcs = dcbe->heads; - encoder->possible_clones = 0; - drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type); - drm_encoder_helper_add(encoder, &nv50_pior_hfunc); - - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} - /****************************************************************************** * Init *****************************************************************************/ @@ -2117,7 +1923,7 @@ nv50_display_init(struct drm_device *dev) evo_mthd(push, 0x0088, 1); evo_data(push, NvEvoSync); evo_kick(push, nv50_mast(dev)); - return 0; + return evo_sync(dev); } return -EBUSY; @@ -2223,28 +2029,25 @@ nv50_display_create(struct drm_device *dev) if (IS_ERR(connector)) continue; - if (dcbe->location == DCB_LOC_ON_CHIP) { - switch (dcbe->type) { - case DCB_OUTPUT_TMDS: - case DCB_OUTPUT_LVDS: - case DCB_OUTPUT_DP: - ret = nv50_sor_create(connector, dcbe); - break; - case DCB_OUTPUT_ANALOG: - ret = nv50_dac_create(connector, dcbe); - break; - default: - ret = -ENODEV; - break; - } - } else { - ret = nv50_pior_create(connector, dcbe); + if (dcbe->location != DCB_LOC_ON_CHIP) { + NV_WARN(drm, "skipping off-chip encoder %d/%d\n", + dcbe->type, ffs(dcbe->or) - 1); + continue; } - if (ret) { - NV_WARN(drm, "failed to create encoder %d/%d/%d: %d\n", - dcbe->location, dcbe->type, - ffs(dcbe->or) - 1, ret); + switch (dcbe->type) { + case DCB_OUTPUT_TMDS: + case DCB_OUTPUT_LVDS: + case DCB_OUTPUT_DP: + nv50_sor_create(connector, dcbe); + break; + case DCB_OUTPUT_ANALOG: + nv50_dac_create(connector, dcbe); + break; + default: + NV_WARN(drm, "skipping unsupported encoder %d/%d\n", + dcbe->type, ffs(dcbe->or) - 1); + continue; } } diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_fence.c b/trunk/drivers/gpu/drm/nouveau/nv50_fence.c index f9701e567db8..d889f3ac0d41 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_fence.c @@ -27,16 +27,27 @@ #include "nouveau_drm.h" #include "nouveau_dma.h" -#include "nv10_fence.h" +#include "nouveau_fence.h" #include "nv50_display.h" +struct nv50_fence_chan { + struct nouveau_fence_chan base; +}; + +struct nv50_fence_priv { + struct nouveau_fence_priv base; + struct nouveau_bo *bo; + spinlock_t lock; + u32 sequence; +}; + static int nv50_fence_context_new(struct nouveau_channel *chan) { struct drm_device *dev = chan->drm->dev; - struct nv10_fence_priv *priv = chan->drm->fence; - struct nv10_fence_chan *fctx; + struct nv50_fence_priv *priv = chan->drm->fence; + struct nv50_fence_chan *fctx; struct ttm_mem_reg *mem = &priv->bo->bo.mem; struct nouveau_object *object; int ret, i; @@ -46,9 +57,6 @@ nv50_fence_context_new(struct nouveau_channel *chan) return -ENOMEM; nouveau_fence_context_new(&fctx->base); - fctx->base.emit = nv10_fence_emit; - fctx->base.read = nv10_fence_read; - fctx->base.sync = nv17_fence_sync; ret = nouveau_object_new(nv_object(chan->cli), chan->handle, NvSema, 0x0002, @@ -83,7 +91,7 @@ nv50_fence_context_new(struct nouveau_channel *chan) int nv50_fence_create(struct nouveau_drm *drm) { - struct nv10_fence_priv *priv; + struct nv50_fence_priv *priv; int ret = 0; priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -91,9 +99,11 @@ nv50_fence_create(struct nouveau_drm *drm) return -ENOMEM; priv->base.dtor = nv10_fence_destroy; - priv->base.resume = nv17_fence_resume; priv->base.context_new = nv50_fence_context_new; priv->base.context_del = nv10_fence_context_del; + priv->base.emit = nv10_fence_emit; + priv->base.read = nv10_fence_read; + priv->base.sync = nv17_fence_sync; spin_lock_init(&priv->lock); ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, @@ -109,11 +119,13 @@ nv50_fence_create(struct nouveau_drm *drm) nouveau_bo_ref(NULL, &priv->bo); } - if (ret) { - nv10_fence_destroy(drm); - return ret; + if (ret == 0) { + nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); + priv->base.sync = nv17_fence_sync; + priv->base.resume = nv17_fence_resume; } - nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); + if (ret) + nv10_fence_destroy(drm); return ret; } diff --git a/trunk/drivers/gpu/drm/nouveau/nv84_fence.c b/trunk/drivers/gpu/drm/nouveau/nv84_fence.c index 9fd475c89820..c686650584b6 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nv84_fence.c @@ -23,7 +23,6 @@ */ #include -#include #include #include @@ -34,115 +33,79 @@ #include "nv50_display.h" -u64 -nv84_fence_crtc(struct nouveau_channel *chan, int crtc) -{ - struct nv84_fence_chan *fctx = chan->fence; - return fctx->dispc_vma[crtc].offset; -} +struct nv84_fence_chan { + struct nouveau_fence_chan base; +}; + +struct nv84_fence_priv { + struct nouveau_fence_priv base; + struct nouveau_gpuobj *mem; +}; static int -nv84_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +nv84_fence_emit(struct nouveau_fence *fence) { - int ret = RING_SPACE(chan, 8); + struct nouveau_channel *chan = fence->channel; + struct nouveau_fifo_chan *fifo = (void *)chan->object; + int ret = RING_SPACE(chan, 7); if (ret == 0) { BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 5); - OUT_RING (chan, upper_32_bits(virtual)); - OUT_RING (chan, lower_32_bits(virtual)); - OUT_RING (chan, sequence); + OUT_RING (chan, NvSema); + BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(fifo->chid * 16)); + OUT_RING (chan, lower_32_bits(fifo->chid * 16)); + OUT_RING (chan, fence->sequence); OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); - OUT_RING (chan, 0x00000000); FIRE_RING (chan); } return ret; } + static int -nv84_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +nv84_fence_sync(struct nouveau_fence *fence, + struct nouveau_channel *prev, struct nouveau_channel *chan) { + struct nouveau_fifo_chan *fifo = (void *)prev->object; int ret = RING_SPACE(chan, 7); if (ret == 0) { BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram); + OUT_RING (chan, NvSema); BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(virtual)); - OUT_RING (chan, lower_32_bits(virtual)); - OUT_RING (chan, sequence); + OUT_RING (chan, upper_32_bits(fifo->chid * 16)); + OUT_RING (chan, lower_32_bits(fifo->chid * 16)); + OUT_RING (chan, fence->sequence); OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL); FIRE_RING (chan); } return ret; } -static int -nv84_fence_emit(struct nouveau_fence *fence) -{ - struct nouveau_channel *chan = fence->channel; - struct nv84_fence_chan *fctx = chan->fence; - struct nouveau_fifo_chan *fifo = (void *)chan->object; - u64 addr = fifo->chid * 16; - - if (fence->sysmem) - addr += fctx->vma_gart.offset; - else - addr += fctx->vma.offset; - - return fctx->base.emit32(chan, addr, fence->sequence); -} - -static int -nv84_fence_sync(struct nouveau_fence *fence, - struct nouveau_channel *prev, struct nouveau_channel *chan) -{ - struct nv84_fence_chan *fctx = chan->fence; - struct nouveau_fifo_chan *fifo = (void *)prev->object; - u64 addr = fifo->chid * 16; - - if (fence->sysmem) - addr += fctx->vma_gart.offset; - else - addr += fctx->vma.offset; - - return fctx->base.sync32(chan, addr, fence->sequence); -} - static u32 nv84_fence_read(struct nouveau_channel *chan) { struct nouveau_fifo_chan *fifo = (void *)chan->object; struct nv84_fence_priv *priv = chan->drm->fence; - return nouveau_bo_rd32(priv->bo, fifo->chid * 16/4); + return nv_ro32(priv->mem, fifo->chid * 16); } static void nv84_fence_context_del(struct nouveau_channel *chan) { - struct drm_device *dev = chan->drm->dev; - struct nv84_fence_priv *priv = chan->drm->fence; struct nv84_fence_chan *fctx = chan->fence; - int i; - - for (i = 0; i < dev->mode_config.num_crtc; i++) { - struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); - nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]); - } - - nouveau_bo_vma_del(priv->bo, &fctx->vma_gart); - nouveau_bo_vma_del(priv->bo, &fctx->vma); nouveau_fence_context_del(&fctx->base); chan->fence = NULL; kfree(fctx); } -int +static int nv84_fence_context_new(struct nouveau_channel *chan) { + struct drm_device *dev = chan->drm->dev; struct nouveau_fifo_chan *fifo = (void *)chan->object; - struct nouveau_client *client = nouveau_client(fifo); struct nv84_fence_priv *priv = chan->drm->fence; struct nv84_fence_chan *fctx; + struct nouveau_object *object; int ret, i; fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); @@ -150,74 +113,44 @@ nv84_fence_context_new(struct nouveau_channel *chan) return -ENOMEM; nouveau_fence_context_new(&fctx->base); - fctx->base.emit = nv84_fence_emit; - fctx->base.sync = nv84_fence_sync; - fctx->base.read = nv84_fence_read; - fctx->base.emit32 = nv84_fence_emit32; - fctx->base.sync32 = nv84_fence_sync32; - ret = nouveau_bo_vma_add(priv->bo, client->vm, &fctx->vma); - if (ret == 0) { - ret = nouveau_bo_vma_add(priv->bo_gart, client->vm, - &fctx->vma_gart); - } + ret = nouveau_object_new(nv_object(chan->cli), chan->handle, + NvSema, 0x0002, + &(struct nv_dma_class) { + .flags = NV_DMA_TARGET_VRAM | + NV_DMA_ACCESS_RDWR, + .start = priv->mem->addr, + .limit = priv->mem->addr + + priv->mem->size - 1, + }, sizeof(struct nv_dma_class), + &object); + + /* dma objects for display sync channel semaphore blocks */ + for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { + struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); - /* map display semaphore buffers into channel's vm */ - for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) { - struct nouveau_bo *bo = nv50_display_crtc_sema(chan->drm->dev, i); - ret = nouveau_bo_vma_add(bo, client->vm, &fctx->dispc_vma[i]); + ret = nouveau_object_new(nv_object(chan->cli), chan->handle, + NvEvoSema0 + i, 0x003d, + &(struct nv_dma_class) { + .flags = NV_DMA_TARGET_VRAM | + NV_DMA_ACCESS_RDWR, + .start = bo->bo.offset, + .limit = bo->bo.offset + 0xfff, + }, sizeof(struct nv_dma_class), + &object); } - nouveau_bo_wr32(priv->bo, fifo->chid * 16/4, 0x00000000); - if (ret) nv84_fence_context_del(chan); + nv_wo32(priv->mem, fifo->chid * 16, 0x00000000); return ret; } -static bool -nv84_fence_suspend(struct nouveau_drm *drm) -{ - struct nouveau_fifo *pfifo = nouveau_fifo(drm->device); - struct nv84_fence_priv *priv = drm->fence; - int i; - - priv->suspend = vmalloc((pfifo->max + 1) * sizeof(u32)); - if (priv->suspend) { - for (i = 0; i <= pfifo->max; i++) - priv->suspend[i] = nouveau_bo_rd32(priv->bo, i*4); - } - - return priv->suspend != NULL; -} - -static void -nv84_fence_resume(struct nouveau_drm *drm) -{ - struct nouveau_fifo *pfifo = nouveau_fifo(drm->device); - struct nv84_fence_priv *priv = drm->fence; - int i; - - if (priv->suspend) { - for (i = 0; i <= pfifo->max; i++) - nouveau_bo_wr32(priv->bo, i*4, priv->suspend[i]); - vfree(priv->suspend); - priv->suspend = NULL; - } -} - static void nv84_fence_destroy(struct nouveau_drm *drm) { struct nv84_fence_priv *priv = drm->fence; - nouveau_bo_unmap(priv->bo_gart); - if (priv->bo_gart) - nouveau_bo_unpin(priv->bo_gart); - nouveau_bo_ref(NULL, &priv->bo_gart); - nouveau_bo_unmap(priv->bo); - if (priv->bo) - nouveau_bo_unpin(priv->bo); - nouveau_bo_ref(NULL, &priv->bo); + nouveau_gpuobj_ref(NULL, &priv->mem); drm->fence = NULL; kfree(priv); } @@ -227,6 +160,7 @@ nv84_fence_create(struct nouveau_drm *drm) { struct nouveau_fifo *pfifo = nouveau_fifo(drm->device); struct nv84_fence_priv *priv; + u32 chan = pfifo->max + 1; int ret; priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -234,42 +168,14 @@ nv84_fence_create(struct nouveau_drm *drm) return -ENOMEM; priv->base.dtor = nv84_fence_destroy; - priv->base.suspend = nv84_fence_suspend; - priv->base.resume = nv84_fence_resume; priv->base.context_new = nv84_fence_context_new; priv->base.context_del = nv84_fence_context_del; + priv->base.emit = nv84_fence_emit; + priv->base.sync = nv84_fence_sync; + priv->base.read = nv84_fence_read; - init_waitqueue_head(&priv->base.waiting); - priv->base.uevent = true; - - ret = nouveau_bo_new(drm->dev, 16 * (pfifo->max + 1), 0, - TTM_PL_FLAG_VRAM, 0, 0, NULL, &priv->bo); - if (ret == 0) { - ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); - if (ret == 0) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_ref(NULL, &priv->bo); - } - - if (ret == 0) - ret = nouveau_bo_new(drm->dev, 16 * (pfifo->max + 1), 0, - TTM_PL_FLAG_TT, 0, 0, NULL, - &priv->bo_gart); - if (ret == 0) { - ret = nouveau_bo_pin(priv->bo_gart, TTM_PL_FLAG_TT); - if (ret == 0) { - ret = nouveau_bo_map(priv->bo_gart); - if (ret) - nouveau_bo_unpin(priv->bo_gart); - } - if (ret) - nouveau_bo_ref(NULL, &priv->bo_gart); - } - + ret = nouveau_gpuobj_new(drm->device, NULL, chan * 16, 0x1000, 0, + &priv->mem); if (ret) nv84_fence_destroy(drm); return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/nvc0_fence.c b/trunk/drivers/gpu/drm/nouveau/nvc0_fence.c index 9566267fbc42..2a56b1b551cb 100644 --- a/trunk/drivers/gpu/drm/nouveau/nvc0_fence.c +++ b/trunk/drivers/gpu/drm/nouveau/nvc0_fence.c @@ -34,57 +34,203 @@ #include "nv50_display.h" +struct nvc0_fence_priv { + struct nouveau_fence_priv base; + struct nouveau_bo *bo; + u32 *suspend; +}; + +struct nvc0_fence_chan { + struct nouveau_fence_chan base; + struct nouveau_vma vma; + struct nouveau_vma dispc_vma[4]; +}; + +u64 +nvc0_fence_crtc(struct nouveau_channel *chan, int crtc) +{ + struct nvc0_fence_chan *fctx = chan->fence; + return fctx->dispc_vma[crtc].offset; +} + static int -nvc0_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +nvc0_fence_emit(struct nouveau_fence *fence) { - int ret = RING_SPACE(chan, 6); + struct nouveau_channel *chan = fence->channel; + struct nvc0_fence_chan *fctx = chan->fence; + struct nouveau_fifo_chan *fifo = (void *)chan->object; + u64 addr = fctx->vma.offset + fifo->chid * 16; + int ret; + + ret = RING_SPACE(chan, 5); if (ret == 0) { - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 5); - OUT_RING (chan, upper_32_bits(virtual)); - OUT_RING (chan, lower_32_bits(virtual)); - OUT_RING (chan, sequence); + BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(addr)); + OUT_RING (chan, lower_32_bits(addr)); + OUT_RING (chan, fence->sequence); OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); - OUT_RING (chan, 0x00000000); FIRE_RING (chan); } + return ret; } static int -nvc0_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +nvc0_fence_sync(struct nouveau_fence *fence, + struct nouveau_channel *prev, struct nouveau_channel *chan) { - int ret = RING_SPACE(chan, 5); + struct nvc0_fence_chan *fctx = chan->fence; + struct nouveau_fifo_chan *fifo = (void *)prev->object; + u64 addr = fctx->vma.offset + fifo->chid * 16; + int ret; + + ret = RING_SPACE(chan, 5); if (ret == 0) { BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(virtual)); - OUT_RING (chan, lower_32_bits(virtual)); - OUT_RING (chan, sequence); + OUT_RING (chan, upper_32_bits(addr)); + OUT_RING (chan, lower_32_bits(addr)); + OUT_RING (chan, fence->sequence); OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL | NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); FIRE_RING (chan); } + return ret; } +static u32 +nvc0_fence_read(struct nouveau_channel *chan) +{ + struct nouveau_fifo_chan *fifo = (void *)chan->object; + struct nvc0_fence_priv *priv = chan->drm->fence; + return nouveau_bo_rd32(priv->bo, fifo->chid * 16/4); +} + +static void +nvc0_fence_context_del(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->drm->dev; + struct nvc0_fence_priv *priv = chan->drm->fence; + struct nvc0_fence_chan *fctx = chan->fence; + int i; + + for (i = 0; i < dev->mode_config.num_crtc; i++) { + struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); + nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]); + } + + nouveau_bo_vma_del(priv->bo, &fctx->vma); + nouveau_fence_context_del(&fctx->base); + chan->fence = NULL; + kfree(fctx); +} + static int nvc0_fence_context_new(struct nouveau_channel *chan) { - int ret = nv84_fence_context_new(chan); - if (ret == 0) { - struct nv84_fence_chan *fctx = chan->fence; - fctx->base.emit32 = nvc0_fence_emit32; - fctx->base.sync32 = nvc0_fence_sync32; + struct nouveau_fifo_chan *fifo = (void *)chan->object; + struct nouveau_client *client = nouveau_client(fifo); + struct nvc0_fence_priv *priv = chan->drm->fence; + struct nvc0_fence_chan *fctx; + int ret, i; + + fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); + if (!fctx) + return -ENOMEM; + + nouveau_fence_context_new(&fctx->base); + + ret = nouveau_bo_vma_add(priv->bo, client->vm, &fctx->vma); + if (ret) + nvc0_fence_context_del(chan); + + /* map display semaphore buffers into channel's vm */ + for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) { + struct nouveau_bo *bo = nv50_display_crtc_sema(chan->drm->dev, i); + ret = nouveau_bo_vma_add(bo, client->vm, &fctx->dispc_vma[i]); } + + nouveau_bo_wr32(priv->bo, fifo->chid * 16/4, 0x00000000); return ret; } +static bool +nvc0_fence_suspend(struct nouveau_drm *drm) +{ + struct nouveau_fifo *pfifo = nouveau_fifo(drm->device); + struct nvc0_fence_priv *priv = drm->fence; + int i; + + priv->suspend = vmalloc((pfifo->max + 1) * sizeof(u32)); + if (priv->suspend) { + for (i = 0; i <= pfifo->max; i++) + priv->suspend[i] = nouveau_bo_rd32(priv->bo, i); + } + + return priv->suspend != NULL; +} + +static void +nvc0_fence_resume(struct nouveau_drm *drm) +{ + struct nouveau_fifo *pfifo = nouveau_fifo(drm->device); + struct nvc0_fence_priv *priv = drm->fence; + int i; + + if (priv->suspend) { + for (i = 0; i <= pfifo->max; i++) + nouveau_bo_wr32(priv->bo, i, priv->suspend[i]); + vfree(priv->suspend); + priv->suspend = NULL; + } +} + +static void +nvc0_fence_destroy(struct nouveau_drm *drm) +{ + struct nvc0_fence_priv *priv = drm->fence; + nouveau_bo_unmap(priv->bo); + if (priv->bo) + nouveau_bo_unpin(priv->bo); + nouveau_bo_ref(NULL, &priv->bo); + drm->fence = NULL; + kfree(priv); +} + int nvc0_fence_create(struct nouveau_drm *drm) { - int ret = nv84_fence_create(drm); + struct nouveau_fifo *pfifo = nouveau_fifo(drm->device); + struct nvc0_fence_priv *priv; + int ret; + + priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->base.dtor = nvc0_fence_destroy; + priv->base.suspend = nvc0_fence_suspend; + priv->base.resume = nvc0_fence_resume; + priv->base.context_new = nvc0_fence_context_new; + priv->base.context_del = nvc0_fence_context_del; + priv->base.emit = nvc0_fence_emit; + priv->base.sync = nvc0_fence_sync; + priv->base.read = nvc0_fence_read; + + ret = nouveau_bo_new(drm->dev, 16 * (pfifo->max + 1), 0, + TTM_PL_FLAG_VRAM, 0, 0, NULL, &priv->bo); if (ret == 0) { - struct nv84_fence_priv *priv = drm->fence; - priv->base.context_new = nvc0_fence_context_new; + ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); + if (ret == 0) { + ret = nouveau_bo_map(priv->bo); + if (ret) + nouveau_bo_unpin(priv->bo); + } + if (ret) + nouveau_bo_ref(NULL, &priv->bo); } + + if (ret) + nvc0_fence_destroy(drm); return ret; } diff --git a/trunk/drivers/gpu/drm/omapdrm/TODO b/trunk/drivers/gpu/drm/omapdrm/TODO deleted file mode 100644 index 4d8c18aa5dd7..000000000000 --- a/trunk/drivers/gpu/drm/omapdrm/TODO +++ /dev/null @@ -1,23 +0,0 @@ -TODO -. Where should we do eviction (detatch_pages())? We aren't necessarily - accessing the pages via a GART, so maybe we need some other threshold - to put a cap on the # of pages that can be pin'd. - . Use mm_shrinker to trigger unpinning pages. - . This is mainly theoretical since most of these devices don't actually - have swap or harddrive. -. GEM/shmem backed pages can have existing mappings (kernel linear map, - etc..), which isn't really ideal. -. Revisit GEM sync object infrastructure.. TTM has some framework for this - already. Possibly this could be refactored out and made more common? - There should be some way to do this with less wheel-reinvention. - . This can be handled by the dma-buf fence/reservation stuff when it - lands - -Userspace: -. git://anongit.freedesktop.org/xorg/driver/xf86-video-omap - -Currently tested on -. OMAP3530 beagleboard -. OMAP4430 pandaboard -. OMAP4460 pandaboard -. OMAP5432 uEVM diff --git a/trunk/drivers/gpu/drm/radeon/atom.c b/trunk/drivers/gpu/drm/radeon/atom.c index 46a9c3772850..5ce9bf51a8de 100644 --- a/trunk/drivers/gpu/drm/radeon/atom.c +++ b/trunk/drivers/gpu/drm/radeon/atom.c @@ -1238,8 +1238,6 @@ static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; static void atom_index_iio(struct atom_context *ctx, int base) { ctx->iio = kzalloc(2 * 256, GFP_KERNEL); - if (!ctx->iio) - return; while (CU8(base) == ATOM_IIO_START) { ctx->iio[CU8(base + 1)] = base + 2; base += 2; @@ -1289,10 +1287,6 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) ctx->cmd_table = CU16(base + ATOM_ROM_CMD_PTR); ctx->data_table = CU16(base + ATOM_ROM_DATA_PTR); atom_index_iio(ctx, CU16(ctx->data_table + ATOM_DATA_IIO_PTR) + 4); - if (!ctx->iio) { - atom_destroy(ctx); - return NULL; - } str = CSTR(CU16(base + ATOM_ROM_MSG_PTR)); while (*str && ((*str == '\n') || (*str == '\r'))) @@ -1341,7 +1335,8 @@ int atom_asic_init(struct atom_context *ctx) void atom_destroy(struct atom_context *ctx) { - kfree(ctx->iio); + if (ctx->iio) + kfree(ctx->iio); kfree(ctx); } diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 3c38ea46531c..2916de896a60 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -403,19 +403,6 @@ void evergreen_pm_misc(struct radeon_device *rdev) rdev->pm.current_vddc = voltage->voltage; DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); } - - /* starting with BTC, there is one state that is used for both - * MH and SH. Difference is that we always use the high clock index for - * mclk and vddci. - */ - if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && - (rdev->family >= CHIP_BARTS) && - rdev->pm.active_crtc_count && - ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) || - (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX))) - voltage = &rdev->pm.power_state[req_ps_idx]. - clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage; - /* 0xff01 is a flag rather then an actual voltage */ if (voltage->vddci == 0xff01) return; diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 6d4b5611daf4..dbcb0752f083 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -109,19 +109,6 @@ void r600_fini(struct radeon_device *rdev); void r600_irq_disable(struct radeon_device *rdev); static void r600_pcie_gen2_enable(struct radeon_device *rdev); -/** - * r600_get_xclk - get the xclk - * - * @rdev: radeon_device pointer - * - * Returns the reference clock used by the gfx engine - * (r6xx, IGPs, APUs). - */ -u32 r600_get_xclk(struct radeon_device *rdev) -{ - return rdev->clock.spll.reference_freq; -} - /* get temperature in millidegrees */ int rv6xx_get_temp(struct radeon_device *rdev) { @@ -4461,14 +4448,14 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) } /** - * r600_get_gpu_clock_counter - return GPU clock counter snapshot + * r600_get_gpu_clock - return GPU clock counter snapshot * * @rdev: radeon_device pointer * * Fetches a GPU clock counter snapshot (R6xx-cayman). * Returns the 64 bit clock counter snapshot. */ -uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev) +uint64_t r600_get_gpu_clock(struct radeon_device *rdev) { uint64_t clock; diff --git a/trunk/drivers/gpu/drm/radeon/r600_hdmi.c b/trunk/drivers/gpu/drm/radeon/r600_hdmi.c index 95970ec47c45..ff80efe9cb7d 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/trunk/drivers/gpu/drm/radeon/r600_hdmi.c @@ -544,6 +544,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) /* Called for ATOM_ENCODER_MODE_HDMI only */ if (!dig || !dig->afmt) { + WARN_ON(1); return; } if (!dig->afmt->enabled) diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 8263af3fd832..bb43a849759b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -1178,10 +1178,6 @@ struct radeon_asic { bool (*gui_idle)(struct radeon_device *rdev); /* wait for mc_idle */ int (*mc_wait_for_idle)(struct radeon_device *rdev); - /* get the reference clock */ - u32 (*get_xclk)(struct radeon_device *rdev); - /* get the gpu clock counter */ - uint64_t (*get_gpu_clock_counter)(struct radeon_device *rdev); /* gart */ struct { void (*tlb_flush)(struct radeon_device *rdev); @@ -1863,8 +1859,6 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) -#define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev)) -#define radeon_get_gpu_clock_counter(rdev) (rdev)->asic->get_gpu_clock_counter((rdev)) /* Common functions */ /* AGP */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.c b/trunk/drivers/gpu/drm/radeon/radeon_asic.c index aba0a893ea98..67f008febec7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.c @@ -934,8 +934,6 @@ static struct radeon_asic r600_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &r600_mc_wait_for_idle, - .get_xclk = &r600_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &r600_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1020,8 +1018,6 @@ static struct radeon_asic rs780_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &r600_mc_wait_for_idle, - .get_xclk = &r600_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &r600_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1106,8 +1102,6 @@ static struct radeon_asic rv770_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &r600_mc_wait_for_idle, - .get_xclk = &rv770_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &r600_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1192,8 +1186,6 @@ static struct radeon_asic evergreen_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .get_xclk = &rv770_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &evergreen_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1278,8 +1270,6 @@ static struct radeon_asic sumo_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .get_xclk = &r600_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &evergreen_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1364,8 +1354,6 @@ static struct radeon_asic btc_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .get_xclk = &rv770_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &evergreen_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1450,8 +1438,6 @@ static struct radeon_asic cayman_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .get_xclk = &rv770_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &cayman_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1579,8 +1565,6 @@ static struct radeon_asic trinity_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .get_xclk = &r600_get_xclk, - .get_gpu_clock_counter = &r600_get_gpu_clock_counter, .gart = { .tlb_flush = &cayman_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, @@ -1708,8 +1692,6 @@ static struct radeon_asic si_asic = { .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .get_xclk = &si_get_xclk, - .get_gpu_clock_counter = &si_get_gpu_clock_counter, .gart = { .tlb_flush = &si_pcie_gart_tlb_flush, .set_page = &rs600_gart_set_page, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.h b/trunk/drivers/gpu/drm/radeon/radeon_asic.h index 3535f73ad3e2..f4134a823958 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.h @@ -389,8 +389,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_sa_bo *vb); int r600_mc_wait_for_idle(struct radeon_device *rdev); -u32 r600_get_xclk(struct radeon_device *rdev); -uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev); +uint64_t r600_get_gpu_clock(struct radeon_device *rdev); /* * rv770,rv730,rv710,rv740 @@ -408,7 +407,6 @@ int rv770_copy_dma(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, unsigned num_gpu_pages, struct radeon_fence **fence); -u32 rv770_get_xclk(struct radeon_device *rdev); /* * evergreen @@ -517,12 +515,11 @@ void si_vm_set_page(struct radeon_device *rdev, 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); +uint64_t si_get_gpu_clock(struct radeon_device *rdev); 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_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); #endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c index d96070bf8388..15f5ded65e0c 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -43,12 +43,6 @@ struct atpx_verify_interface { u32 function_bits; /* supported functions bit vector */ } __packed; -struct atpx_px_params { - u16 size; /* structure size in bytes (includes size field) */ - u32 valid_flags; /* which flags are valid */ - u32 flags; /* flags */ -} __packed; - struct atpx_power_control { u16 size; u8 dgpu_state; @@ -128,62 +122,10 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED; } -/** - * radeon_atpx_validate_functions - validate ATPX functions - * - * @atpx: radeon atpx struct - * - * Validate that required functions are enabled (all asics). - * returns 0 on success, error on failure. - */ -static int radeon_atpx_validate(struct radeon_atpx *atpx) -{ - /* make sure required functions are enabled */ - /* dGPU power control is required */ - atpx->functions.power_cntl = true; - - if (atpx->functions.px_params) { - union acpi_object *info; - struct atpx_px_params output; - size_t size; - u32 valid_bits; - - info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); - if (!info) - return -EIO; - - memset(&output, 0, sizeof(output)); - - size = *(u16 *) info->buffer.pointer; - if (size < 10) { - printk("ATPX buffer is too small: %zu\n", size); - kfree(info); - return -EINVAL; - } - size = min(sizeof(output), size); - - memcpy(&output, info->buffer.pointer, size); - - valid_bits = output.flags & output.valid_flags; - /* if separate mux flag is set, mux controls are required */ - if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { - atpx->functions.i2c_mux_cntl = true; - atpx->functions.disp_mux_cntl = true; - } - /* if any outputs are muxed, mux controls are required */ - if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | - ATPX_TV_SIGNAL_MUXED | - ATPX_DFP_SIGNAL_MUXED)) - atpx->functions.disp_mux_cntl = true; - - kfree(info); - } - return 0; -} - /** * radeon_atpx_verify_interface - verify ATPX * + * @handle: acpi handle * @atpx: radeon atpx struct * * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function @@ -464,19 +406,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) */ static int radeon_atpx_init(void) { - int r; - /* set up the ATPX handle */ - r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); - if (r) - return r; - - /* validate the atpx setup */ - r = radeon_atpx_validate(&radeon_atpx_priv.atpx); - if (r) - return r; - - return 0; + return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); } /** diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 44b8034a400d..8794de10a6c7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -759,11 +759,6 @@ int radeon_atombios_init(struct radeon_device *rdev) atom_card_info->pll_write = cail_pll_write; rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); - if (!rdev->mode_info.atom_context) { - radeon_atombios_fini(rdev); - return -ENOMEM; - } - mutex_init(&rdev->mode_info.atom_context->mutex); radeon_atom_initialize_bios_scratch_regs(rdev->ddev); atom_allocate_fb_scratch(rdev->mode_info.atom_context); @@ -783,11 +778,9 @@ void radeon_atombios_fini(struct radeon_device *rdev) { if (rdev->mode_info.atom_context) { kfree(rdev->mode_info.atom_context->scratch); + kfree(rdev->mode_info.atom_context); } - kfree(rdev->mode_info.atom_context); - rdev->mode_info.atom_context = NULL; kfree(rdev->mode_info.atom_card_info); - rdev->mode_info.atom_card_info = NULL; } /* COMBIOS */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_kms.c index c75cb2c6ba71..9c312f9afb68 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_kms.c @@ -185,7 +185,11 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (info->request == RADEON_INFO_TIMESTAMP) { if (rdev->family >= CHIP_R600) { value_ptr64 = (uint64_t*)((unsigned long)info->value); - value64 = radeon_get_gpu_clock_counter(rdev); + if (rdev->family >= CHIP_TAHITI) { + value64 = si_get_gpu_clock(rdev); + } else { + value64 = r600_get_gpu_clock(rdev); + } if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); @@ -278,10 +282,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) break; case RADEON_INFO_CLOCK_CRYSTAL_FREQ: /* return clock value in KHz */ - if (rdev->asic->get_xclk) - value = radeon_get_xclk(rdev) * 10; - else - value = rdev->clock.spll.reference_freq * 10; + value = rdev->clock.spll.reference_freq * 10; break; case RADEON_INFO_NUM_BACKENDS: if (rdev->family >= CHIP_TAHITI) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_pm.c b/trunk/drivers/gpu/drm/radeon/radeon_pm.c index 338fd6a74e87..0bfa656aa87d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_pm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_pm.c @@ -169,7 +169,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) /* starting with BTC, there is one state that is used for both * MH and SH. Difference is that we always use the high clock index for - * mclk and vddci. + * mclk. */ if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && (rdev->family >= CHIP_BARTS) && diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index d63fe1d0f53f..1b2444f4d8f4 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -43,31 +43,6 @@ static void rv770_gpu_init(struct radeon_device *rdev); void rv770_fini(struct radeon_device *rdev); static void rv770_pcie_gen2_enable(struct radeon_device *rdev); -#define PCIE_BUS_CLK 10000 -#define TCLK (PCIE_BUS_CLK / 10) - -/** - * rv770_get_xclk - get the xclk - * - * @rdev: radeon_device pointer - * - * Returns the reference clock used by the gfx engine - * (r7xx-cayman). - */ -u32 rv770_get_xclk(struct radeon_device *rdev) -{ - u32 reference_clock = rdev->clock.spll.reference_freq; - u32 tmp = RREG32(CG_CLKPIN_CNTL); - - if (tmp & MUX_TCLK_TO_XCLK) - return TCLK; - - if (tmp & XTALIN_DIVIDE) - return reference_clock / 4; - - return reference_clock; -} - u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; diff --git a/trunk/drivers/gpu/drm/radeon/rv770d.h b/trunk/drivers/gpu/drm/radeon/rv770d.h index c55f950a4af7..20e29d23d348 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770d.h +++ b/trunk/drivers/gpu/drm/radeon/rv770d.h @@ -128,10 +128,6 @@ #define GUI_ACTIVE (1<<31) #define GRBM_STATUS2 0x8014 -#define CG_CLKPIN_CNTL 0x660 -# define MUX_TCLK_TO_XCLK (1 << 8) -# define XTALIN_DIVIDE (1 << 9) - #define CG_MULT_THERMAL_STATUS 0x740 #define ASIC_T(x) ((x) << 16) #define ASIC_T_MASK 0x3FF0000 diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 80979ed951eb..719f03e061db 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -70,33 +70,6 @@ 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); -#define PCIE_BUS_CLK 10000 -#define TCLK (PCIE_BUS_CLK / 10) - -/** - * si_get_xclk - get the xclk - * - * @rdev: radeon_device pointer - * - * Returns the reference clock used by the gfx engine - * (SI). - */ -u32 si_get_xclk(struct radeon_device *rdev) -{ - u32 reference_clock = rdev->clock.spll.reference_freq; - u32 tmp; - - tmp = RREG32(CG_CLKPIN_CNTL_2); - if (tmp & MUX_TCLK_TO_XCLK) - return TCLK; - - tmp = RREG32(CG_CLKPIN_CNTL); - if (tmp & XTALIN_DIVIDE) - return reference_clock / 4; - - return reference_clock; -} - /* get temperature in millidegrees */ int si_get_temp(struct radeon_device *rdev) { @@ -4609,14 +4582,14 @@ void si_fini(struct radeon_device *rdev) } /** - * si_get_gpu_clock_counter - return GPU clock counter snapshot + * si_get_gpu_clock - return GPU clock counter snapshot * * @rdev: radeon_device pointer * * Fetches a GPU clock counter snapshot (SI). * Returns the 64 bit clock counter snapshot. */ -uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev) +uint64_t si_get_gpu_clock(struct radeon_device *rdev) { uint64_t clock; diff --git a/trunk/drivers/gpu/drm/radeon/sid.h b/trunk/drivers/gpu/drm/radeon/sid.h index 23fc08fc8e7f..07fc455e35ae 100644 --- a/trunk/drivers/gpu/drm/radeon/sid.h +++ b/trunk/drivers/gpu/drm/radeon/sid.h @@ -58,11 +58,6 @@ #define VGA_HDP_CONTROL 0x328 #define VGA_MEMORY_DISABLE (1 << 4) -#define CG_CLKPIN_CNTL 0x660 -# define XTALIN_DIVIDE (1 << 1) -#define CG_CLKPIN_CNTL_2 0x664 -# define MUX_TCLK_TO_XCLK (1 << 8) - #define DMIF_ADDR_CONFIG 0xBD4 #define SRBM_STATUS 0xE50 diff --git a/trunk/drivers/gpu/stub/Kconfig b/trunk/drivers/gpu/stub/Kconfig new file mode 100644 index 000000000000..419917955bf6 --- /dev/null +++ b/trunk/drivers/gpu/stub/Kconfig @@ -0,0 +1,18 @@ +config STUB_POULSBO + tristate "Intel GMA500 Stub Driver" + depends on PCI + depends on NET # for THERMAL + # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled + # but for select to work, need to select ACPI_VIDEO's dependencies, ick + select BACKLIGHT_CLASS_DEVICE if ACPI + select VIDEO_OUTPUT_CONTROL if ACPI + select INPUT if ACPI + select ACPI_VIDEO if ACPI + select THERMAL if ACPI + help + Choose this option if you have a system that has Intel GMA500 + (Poulsbo) integrated graphics. If M is selected, the module will + be called Poulsbo. This driver is a stub driver for Poulsbo that + will call poulsbo.ko to enable the acpi backlight control sysfs + entry file because there have no poulsbo native driver can support + intel opregion. diff --git a/trunk/drivers/gpu/stub/Makefile b/trunk/drivers/gpu/stub/Makefile new file mode 100644 index 000000000000..cd940cc9d36d --- /dev/null +++ b/trunk/drivers/gpu/stub/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_STUB_POULSBO) += poulsbo.o diff --git a/trunk/drivers/gpu/stub/poulsbo.c b/trunk/drivers/gpu/stub/poulsbo.c new file mode 100644 index 000000000000..7edfd27b8dee --- /dev/null +++ b/trunk/drivers/gpu/stub/poulsbo.c @@ -0,0 +1,64 @@ +/* + * Intel Poulsbo Stub driver + * + * Copyright (C) 2010 Novell + * + * 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 +#include +#include +#include + +#define DRIVER_NAME "poulsbo" + +enum { + CHIP_PSB_8108 = 0, + CHIP_PSB_8109 = 1, +}; + +static DEFINE_PCI_DEVICE_TABLE(pciidlist) = { + {0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108}, \ + {0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109}, \ + {0, 0, 0} +}; + +static int poulsbo_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return acpi_video_register(); +} + +static void poulsbo_remove(struct pci_dev *pdev) +{ + acpi_video_unregister(); +} + +static struct pci_driver poulsbo_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + .probe = poulsbo_probe, + .remove = poulsbo_remove, +}; + +static int __init poulsbo_init(void) +{ + return pci_register_driver(&poulsbo_driver); +} + +static void __exit poulsbo_exit(void) +{ + pci_unregister_driver(&poulsbo_driver); +} + +module_init(poulsbo_init); +module_exit(poulsbo_exit); + +MODULE_AUTHOR("Lee, Chun-Yi "); +MODULE_DESCRIPTION("Poulsbo Stub Driver"); +MODULE_LICENSE("GPL"); + +MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/trunk/drivers/iommu/intel-iommu.c b/trunk/drivers/iommu/intel-iommu.c index f1e7b86a7c37..eca28014ef3e 100644 --- a/trunk/drivers/iommu/intel-iommu.c +++ b/trunk/drivers/iommu/intel-iommu.c @@ -4253,19 +4253,13 @@ static void quirk_iommu_rwbf(struct pci_dev *dev) { /* * Mobile 4 Series Chipset neglects to set RWBF capability, - * but needs it. Same seems to hold for the desktop versions. + * but needs it: */ printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); rwbf_quirk = 1; } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf); #define GGC 0x52 #define GGC_MEMORY_SIZE_MASK (0xf << 8) diff --git a/trunk/drivers/staging/Kconfig b/trunk/drivers/staging/Kconfig index eca907bf8b6d..329bdb42109f 100644 --- a/trunk/drivers/staging/Kconfig +++ b/trunk/drivers/staging/Kconfig @@ -114,6 +114,8 @@ source "drivers/staging/media/Kconfig" source "drivers/staging/net/Kconfig" +source "drivers/staging/omapdrm/Kconfig" + source "drivers/staging/android/Kconfig" source "drivers/staging/ozwpan/Kconfig" diff --git a/trunk/drivers/staging/Makefile b/trunk/drivers/staging/Makefile index d810ed729add..c7ec486680f7 100644 --- a/trunk/drivers/staging/Makefile +++ b/trunk/drivers/staging/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ obj-$(CONFIG_MFD_NVEC) += nvec/ +obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_USB_G_CCG) += ccg/ diff --git a/trunk/drivers/gpu/drm/omapdrm/Kconfig b/trunk/drivers/staging/omapdrm/Kconfig similarity index 100% rename from trunk/drivers/gpu/drm/omapdrm/Kconfig rename to trunk/drivers/staging/omapdrm/Kconfig diff --git a/trunk/drivers/gpu/drm/omapdrm/Makefile b/trunk/drivers/staging/omapdrm/Makefile similarity index 100% rename from trunk/drivers/gpu/drm/omapdrm/Makefile rename to trunk/drivers/staging/omapdrm/Makefile diff --git a/trunk/drivers/staging/omapdrm/TODO b/trunk/drivers/staging/omapdrm/TODO new file mode 100644 index 000000000000..abeeb00aaa12 --- /dev/null +++ b/trunk/drivers/staging/omapdrm/TODO @@ -0,0 +1,32 @@ +TODO +. add video decode/encode support (via syslink3 + codec-engine) + . NOTE: with dmabuf this probably could be split into different driver + so perhaps this TODO doesn't belong here +. where should we do eviction (detatch_pages())? We aren't necessarily + accessing the pages via a GART, so maybe we need some other threshold + to put a cap on the # of pages that can be pin'd. (It is mostly only + of interest in case you have a swap partition/file.. which a lot of + these devices do not.. but it doesn't hurt for the driver to do the + right thing anyways.) + . Use mm_shrinker to trigger unpinning pages. Need to figure out how + to handle next issue first (I think?) + . Note TTM already has some mm_shrinker stuff.. maybe an argument to + move to TTM? Or maybe something that could be factored out in common? +. GEM/shmem backed pages can have existing mappings (kernel linear map, + etc..), which isn't really ideal. +. Revisit GEM sync object infrastructure.. TTM has some framework for this + already. Possibly this could be refactored out and made more common? + There should be some way to do this with less wheel-reinvention. +. Solve PM sequencing on resume. DMM/TILER must be reloaded before any + access is made from any component in the system. Which means on suspend + CRTC's should be disabled, and on resume the LUT should be reprogrammed + before CRTC's are re-enabled, to prevent DSS from trying to DMA from a + buffer mapped in DMM/TILER before LUT is reloaded. + +Userspace: +. git://github.com/robclark/xf86-video-omap.git + +Currently tested on +. OMAP3530 beagleboard +. OMAP4430 pandaboard +. OMAP4460 pandaboard diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_connector.c b/trunk/drivers/staging/omapdrm/omap_connector.c similarity index 99% rename from trunk/drivers/gpu/drm/omapdrm/omap_connector.c rename to trunk/drivers/staging/omapdrm/omap_connector.c index 44284fd981fc..4cc9ee733c5f 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/trunk/drivers/staging/omapdrm/omap_connector.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_connector.c + * drivers/staging/omapdrm/omap_connector.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_crtc.c b/trunk/drivers/staging/omapdrm/omap_crtc.c similarity index 98% rename from trunk/drivers/gpu/drm/omapdrm/omap_crtc.c rename to trunk/drivers/staging/omapdrm/omap_crtc.c index ac2258f59805..510942e67020 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/trunk/drivers/staging/omapdrm/omap_crtc.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_crtc.c + * drivers/staging/omapdrm/omap_crtc.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -274,16 +274,17 @@ static void page_flip_worker(struct work_struct *work) struct omap_crtc *omap_crtc = container_of(work, struct omap_crtc, page_flip_work); struct drm_crtc *crtc = &omap_crtc->base; + struct drm_device *dev = crtc->dev; struct drm_display_mode *mode = &crtc->mode; struct drm_gem_object *bo; - mutex_lock(&crtc->mutex); + drm_modeset_lock_all(dev); omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, 0, 0, mode->hdisplay, mode->vdisplay, crtc->x << 16, crtc->y << 16, mode->hdisplay << 16, mode->vdisplay << 16, vblank_cb, crtc); - mutex_unlock(&crtc->mutex); + drm_modeset_unlock_all(dev); bo = omap_framebuffer_bo(crtc->fb, 0); drm_gem_object_unreference_unlocked(bo); @@ -416,7 +417,7 @@ static void apply_worker(struct work_struct *work) * the callbacks and list modification all serialized * with respect to modesetting ioctls from userspace. */ - mutex_lock(&crtc->mutex); + drm_modeset_lock_all(dev); dispc_runtime_get(); /* @@ -461,15 +462,16 @@ static void apply_worker(struct work_struct *work) out: dispc_runtime_put(); - mutex_unlock(&crtc->mutex); + drm_modeset_unlock_all(dev); } int omap_crtc_apply(struct drm_crtc *crtc, struct omap_drm_apply *apply) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_device *dev = crtc->dev; - WARN_ON(!mutex_is_locked(&crtc->mutex)); + WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); /* no need to queue it again if it is already queued: */ if (apply->queued) diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_debugfs.c b/trunk/drivers/staging/omapdrm/omap_debugfs.c similarity index 90% rename from trunk/drivers/gpu/drm/omapdrm/omap_debugfs.c rename to trunk/drivers/staging/omapdrm/omap_debugfs.c index c27f59da7f29..e95540b3e2f6 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_debugfs.c +++ b/trunk/drivers/staging/omapdrm/omap_debugfs.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_debugfs.c + * drivers/staging/omapdrm/omap_debugfs.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -57,6 +57,17 @@ static int fb_show(struct seq_file *m, void *arg) struct drm_device *dev = node->minor->dev; struct omap_drm_private *priv = dev->dev_private; struct drm_framebuffer *fb; + int ret; + + ret = mutex_lock_interruptible(&dev->mode_config.mutex); + if (ret) + return ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) { + mutex_unlock(&dev->mode_config.mutex); + return ret; + } seq_printf(m, "fbcon "); omap_framebuffer_describe(priv->fbdev->fb, m); @@ -71,6 +82,9 @@ static int fb_show(struct seq_file *m, void *arg) } mutex_unlock(&dev->mode_config.fb_lock); + mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev->mode_config.mutex); + return 0; } diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_dmm_priv.h b/trunk/drivers/staging/omapdrm/omap_dmm_priv.h similarity index 96% rename from trunk/drivers/gpu/drm/omapdrm/omap_dmm_priv.h rename to trunk/drivers/staging/omapdrm/omap_dmm_priv.h index 58bcd6ae0255..273ec12c028a 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_dmm_priv.h +++ b/trunk/drivers/staging/omapdrm/omap_dmm_priv.h @@ -118,11 +118,6 @@ struct pat { #define DESCR_SIZE 128 #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE)) -/* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers. - * This is used in programming to address the upper portion of the LUT -*/ -#define OMAP5_LUT_OFFSET 128 - struct dmm; struct dmm_txn { diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/trunk/drivers/staging/omapdrm/omap_dmm_tiler.c similarity index 86% rename from trunk/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c rename to trunk/drivers/staging/omapdrm/omap_dmm_tiler.c index 391021537105..59bf43899fc0 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/trunk/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -213,11 +213,6 @@ static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, txn->last_pat->next_pa = (uint32_t)pat_pa; pat->area = *area; - - /* adjust Y coordinates based off of container parameters */ - pat->area.y0 += engine->tcm->y_offset; - pat->area.y1 += engine->tcm->y_offset; - pat->ctrl = (struct pat_ctrl){ .start = 1, .lut_id = engine->tcm->lut_id, @@ -627,11 +622,6 @@ static int omap_dmm_probe(struct platform_device *dev) omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5; omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5; - /* increment LUT by one if on OMAP5 */ - /* LUT has twice the height, and is split into a separate container */ - if (omap_dmm->lut_height != omap_dmm->container_height) - omap_dmm->num_lut++; - /* initialize DMM registers */ writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0); writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1); @@ -711,9 +701,6 @@ static int omap_dmm_probe(struct platform_device *dev) } /* init containers */ - /* Each LUT is associated with a TCM (container manager). We use the - lut_id to denote the lut_id used to identify the correct LUT for - programming during reill operations */ for (i = 0; i < omap_dmm->num_lut; i++) { omap_dmm->tcm[i] = sita_init(omap_dmm->container_width, omap_dmm->container_height, @@ -730,23 +717,13 @@ static int omap_dmm_probe(struct platform_device *dev) /* assign access mode containers to applicable tcm container */ /* OMAP 4 has 1 container for all 4 views */ - /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */ containers[TILFMT_8BIT] = omap_dmm->tcm[0]; containers[TILFMT_16BIT] = omap_dmm->tcm[0]; containers[TILFMT_32BIT] = omap_dmm->tcm[0]; - - if (omap_dmm->container_height != omap_dmm->lut_height) { - /* second LUT is used for PAGE mode. Programming must use - y offset that is added to all y coordinates. LUT id is still - 0, because it is the same LUT, just the upper 128 lines */ - containers[TILFMT_PAGE] = omap_dmm->tcm[1]; - omap_dmm->tcm[1]->y_offset = OMAP5_LUT_OFFSET; - omap_dmm->tcm[1]->lut_id = 0; - } else { - containers[TILFMT_PAGE] = omap_dmm->tcm[0]; - } + containers[TILFMT_PAGE] = omap_dmm->tcm[0]; area = (struct tcm_area) { + .is2d = true, .tcm = NULL, .p1.x = omap_dmm->container_width - 1, .p1.y = omap_dmm->container_height - 1, @@ -858,81 +835,64 @@ int tiler_map_show(struct seq_file *s, void *arg) int h_adj; int w_adj; unsigned long flags; - int lut_idx; - if (!omap_dmm) { /* early return if dmm/tiler device is not initialized */ return 0; } - h_adj = omap_dmm->container_height / ydiv; - w_adj = omap_dmm->container_width / xdiv; + h_adj = omap_dmm->lut_height / ydiv; + w_adj = omap_dmm->lut_width / xdiv; - map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL); - global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL); + map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL); + global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL); if (!map || !global_map) goto error; - for (lut_idx = 0; lut_idx < omap_dmm->num_lut; lut_idx++) { - memset(map, 0, sizeof(h_adj * sizeof(*map))); - memset(global_map, ' ', (w_adj + 1) * h_adj); - - for (i = 0; i < omap_dmm->container_height; i++) { - map[i] = global_map + i * (w_adj + 1); - map[i][w_adj] = 0; - } - - spin_lock_irqsave(&list_lock, flags); + memset(global_map, ' ', (w_adj + 1) * h_adj); + for (i = 0; i < omap_dmm->lut_height; i++) { + map[i] = global_map + i * (w_adj + 1); + map[i][w_adj] = 0; + } + spin_lock_irqsave(&list_lock, flags); - list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { - if (block->area.tcm == omap_dmm->tcm[lut_idx]) { - if (block->fmt != TILFMT_PAGE) { - fill_map(map, xdiv, ydiv, &block->area, - *m2dp, true); - if (!*++a2dp) - a2dp = a2d; - if (!*++m2dp) - m2dp = m2d; - map_2d_info(map, xdiv, ydiv, nice, - &block->area); - } else { - bool start = read_map_pt(map, xdiv, - ydiv, &block->area.p0) == ' '; - bool end = read_map_pt(map, xdiv, ydiv, - &block->area.p1) == ' '; - - tcm_for_each_slice(a, block->area, p) - fill_map(map, xdiv, ydiv, &a, - '=', true); - fill_map_pt(map, xdiv, ydiv, - &block->area.p0, + list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { + if (block->fmt != TILFMT_PAGE) { + fill_map(map, xdiv, ydiv, &block->area, *m2dp, true); + if (!*++a2dp) + a2dp = a2d; + if (!*++m2dp) + m2dp = m2d; + map_2d_info(map, xdiv, ydiv, nice, &block->area); + } else { + bool start = read_map_pt(map, xdiv, ydiv, + &block->area.p0) + == ' '; + bool end = read_map_pt(map, xdiv, ydiv, &block->area.p1) + == ' '; + tcm_for_each_slice(a, block->area, p) + fill_map(map, xdiv, ydiv, &a, '=', true); + fill_map_pt(map, xdiv, ydiv, &block->area.p0, start ? '<' : 'X'); - fill_map_pt(map, xdiv, ydiv, - &block->area.p1, + fill_map_pt(map, xdiv, ydiv, &block->area.p1, end ? '>' : 'X'); - map_1d_info(map, xdiv, ydiv, nice, - &block->area); - } - } + map_1d_info(map, xdiv, ydiv, nice, &block->area); } + } - spin_unlock_irqrestore(&list_lock, flags); + spin_unlock_irqrestore(&list_lock, flags); - if (s) { - seq_printf(s, "CONTAINER %d DUMP BEGIN\n", lut_idx); - for (i = 0; i < 128; i++) - seq_printf(s, "%03d:%s\n", i, map[i]); - seq_printf(s, "CONTAINER %d DUMP END\n", lut_idx); - } else { - dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP BEGIN\n", - lut_idx); - for (i = 0; i < 128; i++) - dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]); - dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP END\n", - lut_idx); - } + if (s) { + seq_printf(s, "BEGIN DMM TILER MAP\n"); + for (i = 0; i < 128; i++) + seq_printf(s, "%03d:%s\n", i, map[i]); + seq_printf(s, "END TILER MAP\n"); + } else { + dev_dbg(omap_dmm->dev, "BEGIN DMM TILER MAP\n"); + for (i = 0; i < 128; i++) + dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]); + dev_dbg(omap_dmm->dev, "END TILER MAP\n"); } error: @@ -943,45 +903,12 @@ int tiler_map_show(struct seq_file *s, void *arg) } #endif -#ifdef CONFIG_PM -static int omap_dmm_resume(struct device *dev) -{ - struct tcm_area area; - int i; - - if (!omap_dmm) - return -ENODEV; - - area = (struct tcm_area) { - .tcm = NULL, - .p1.x = omap_dmm->container_width - 1, - .p1.y = omap_dmm->container_height - 1, - }; - - /* initialize all LUTs to dummy page entries */ - for (i = 0; i < omap_dmm->num_lut; i++) { - area.tcm = omap_dmm->tcm[i]; - if (fill(&area, NULL, 0, 0, true)) - dev_err(dev, "refill failed"); - } - - return 0; -} - -static const struct dev_pm_ops omap_dmm_pm_ops = { - .resume = omap_dmm_resume, -}; -#endif - struct platform_driver omap_dmm_driver = { .probe = omap_dmm_probe, .remove = omap_dmm_remove, .driver = { .owner = THIS_MODULE, .name = DMM_DRIVER_NAME, -#ifdef CONFIG_PM - .pm = &omap_dmm_pm_ops, -#endif }, }; diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_dmm_tiler.h b/trunk/drivers/staging/omapdrm/omap_dmm_tiler.h similarity index 100% rename from trunk/drivers/gpu/drm/omapdrm/omap_dmm_tiler.h rename to trunk/drivers/staging/omapdrm/omap_dmm_tiler.h diff --git a/trunk/include/uapi/drm/omap_drm.h b/trunk/drivers/staging/omapdrm/omap_drm.h similarity index 99% rename from trunk/include/uapi/drm/omap_drm.h rename to trunk/drivers/staging/omapdrm/omap_drm.h index 1d0b1172664e..f0ac34a8973e 100644 --- a/trunk/include/uapi/drm/omap_drm.h +++ b/trunk/drivers/staging/omapdrm/omap_drm.h @@ -1,5 +1,5 @@ /* - * include/uapi/drm/omap_drm.h + * include/drm/omap_drm.h * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_drv.c b/trunk/drivers/staging/omapdrm/omap_drv.c similarity index 97% rename from trunk/drivers/gpu/drm/omapdrm/omap_drv.c rename to trunk/drivers/staging/omapdrm/omap_drv.c index 9083538bd16a..dfdb4ba1e7c6 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/trunk/drivers/staging/omapdrm/omap_drv.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_drv.c + * drivers/staging/omapdrm/omap_drv.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -368,9 +368,6 @@ static int dev_load(struct drm_device *dev, unsigned long flags) /* well, limp along without an fbdev.. maybe X11 will work? */ } - /* store off drm_device for use in pm ops */ - dev_set_drvdata(dev->dev, dev); - drm_kms_helper_poll_init(dev); return 0; @@ -396,8 +393,6 @@ static int dev_unload(struct drm_device *dev) kfree(dev->dev_private); dev->dev_private = NULL; - dev_set_drvdata(dev->dev, NULL); - return 0; } @@ -563,19 +558,10 @@ static int pdev_remove(struct platform_device *device) return 0; } -#ifdef CONFIG_PM -static const struct dev_pm_ops omapdrm_pm_ops = { - .resume = omap_gem_resume, -}; -#endif - struct platform_driver pdev = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &omapdrm_pm_ops, -#endif }, .probe = pdev_probe, .remove = pdev_remove, diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_drv.h b/trunk/drivers/staging/omapdrm/omap_drv.h similarity index 98% rename from trunk/drivers/gpu/drm/omapdrm/omap_drv.h rename to trunk/drivers/staging/omapdrm/omap_drv.h index d4f997bb4ac0..cd1f22b0b124 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/trunk/drivers/staging/omapdrm/omap_drv.h @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_drv.h + * drivers/staging/omapdrm/omap_drv.h * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include "omap_drm.h" #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) @@ -135,10 +135,6 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m); void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); #endif -#ifdef CONFIG_PM -int omap_gem_resume(struct device *dev); -#endif - int omap_irq_enable_vblank(struct drm_device *dev, int crtc); void omap_irq_disable_vblank(struct drm_device *dev, int crtc); irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_encoder.c b/trunk/drivers/staging/omapdrm/omap_encoder.c similarity index 99% rename from trunk/drivers/gpu/drm/omapdrm/omap_encoder.c rename to trunk/drivers/staging/omapdrm/omap_encoder.c index 7e1f2ab65372..e053160d2db3 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/trunk/drivers/staging/omapdrm/omap_encoder.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_encoder.c + * drivers/staging/omapdrm/omap_encoder.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_fb.c b/trunk/drivers/staging/omapdrm/omap_fb.c similarity index 99% rename from trunk/drivers/gpu/drm/omapdrm/omap_fb.c rename to trunk/drivers/staging/omapdrm/omap_fb.c index 9d5f6f696c72..bf6421f26c40 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/trunk/drivers/staging/omapdrm/omap_fb.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_fb.c + * drivers/staging/omapdrm/omap_fb.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_fbdev.c b/trunk/drivers/staging/omapdrm/omap_fbdev.c similarity index 98% rename from trunk/drivers/gpu/drm/omapdrm/omap_fbdev.c rename to trunk/drivers/staging/omapdrm/omap_fbdev.c index f0033bd3e4ae..caefdf9430f8 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/trunk/drivers/staging/omapdrm/omap_fbdev.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_fbdev.c + * drivers/staging/omapdrm/omap_fbdev.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -131,6 +131,9 @@ static struct fb_ops omap_fb_ops = { .fb_pan_display = omap_fbdev_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 omap_fbdev_create(struct drm_fb_helper *helper, diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_gem.c b/trunk/drivers/staging/omapdrm/omap_gem.c similarity index 97% rename from trunk/drivers/gpu/drm/omapdrm/omap_gem.c rename to trunk/drivers/staging/omapdrm/omap_gem.c index e8302b02691d..c38992b76fc9 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/trunk/drivers/staging/omapdrm/omap_gem.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_gem.c + * drivers/staging/omapdrm/omap_gem.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -964,34 +964,6 @@ void *omap_gem_vaddr(struct drm_gem_object *obj) return omap_obj->vaddr; } -#ifdef CONFIG_PM -/* re-pin objects in DMM in resume path: */ -int omap_gem_resume(struct device *dev) -{ - struct drm_device *drm_dev = dev_get_drvdata(dev); - struct omap_drm_private *priv = drm_dev->dev_private; - struct omap_gem_object *omap_obj; - int ret = 0; - - list_for_each_entry(omap_obj, &priv->obj_list, mm_list) { - if (omap_obj->block) { - struct drm_gem_object *obj = &omap_obj->base; - uint32_t npages = obj->size >> PAGE_SHIFT; - WARN_ON(!omap_obj->pages); /* this can't happen */ - ret = tiler_pin(omap_obj->block, - omap_obj->pages, npages, - omap_obj->roll, true); - if (ret) { - dev_err(dev, "could not repin: %d\n", ret); - return ret; - } - } - } - - return 0; -} -#endif - #ifdef CONFIG_DEBUG_FS void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) { @@ -1267,12 +1239,12 @@ int omap_gem_set_sync_object(struct drm_gem_object *obj, void *syncobj) if ((omap_obj->flags & OMAP_BO_EXT_SYNC) && !syncobj) { /* clearing a previously set syncobj */ - syncobj = kmemdup(omap_obj->sync, sizeof(*omap_obj->sync), - GFP_ATOMIC); + syncobj = kzalloc(sizeof(*omap_obj->sync), GFP_ATOMIC); if (!syncobj) { ret = -ENOMEM; goto unlock; } + memcpy(syncobj, omap_obj->sync, sizeof(*omap_obj->sync)); omap_obj->flags &= ~OMAP_BO_EXT_SYNC; omap_obj->sync = syncobj; } else if (syncobj && !(omap_obj->flags & OMAP_BO_EXT_SYNC)) { diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/trunk/drivers/staging/omapdrm/omap_gem_dmabuf.c similarity index 98% rename from trunk/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c rename to trunk/drivers/staging/omapdrm/omap_gem_dmabuf.c index ac74d1bc67bf..b6c5b5c6c8c5 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c +++ b/trunk/drivers/staging/omapdrm/omap_gem_dmabuf.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c + * drivers/staging/omapdrm/omap_gem_dmabuf.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -53,10 +53,10 @@ static struct sg_table *omap_gem_map_dma_buf( /* this should be after _get_paddr() to ensure we have pages attached */ omap_gem_dma_sync(obj, dir); - return sg; out: - kfree(sg); - return ERR_PTR(ret); + if (ret) + return ERR_PTR(ret); + return sg; } static void omap_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_gem_helpers.c b/trunk/drivers/staging/omapdrm/omap_gem_helpers.c similarity index 98% rename from trunk/drivers/gpu/drm/omapdrm/omap_gem_helpers.c rename to trunk/drivers/staging/omapdrm/omap_gem_helpers.c index e4a66a35fc6a..ffb8cceaeb46 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_gem_helpers.c +++ b/trunk/drivers/staging/omapdrm/omap_gem_helpers.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_gem_helpers.c + * drivers/staging/omapdrm/omap_gem_helpers.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_irq.c b/trunk/drivers/staging/omapdrm/omap_irq.c similarity index 99% rename from trunk/drivers/gpu/drm/omapdrm/omap_irq.c rename to trunk/drivers/staging/omapdrm/omap_irq.c index e01303ee00c3..2629ba7be6c8 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_irq.c +++ b/trunk/drivers/staging/omapdrm/omap_irq.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_irq.c + * drivers/staging/omapdrm/omap_irq.c * * Copyright (C) 2012 Texas Instruments * Author: Rob Clark diff --git a/trunk/drivers/gpu/drm/omapdrm/omap_plane.c b/trunk/drivers/staging/omapdrm/omap_plane.c similarity index 99% rename from trunk/drivers/gpu/drm/omapdrm/omap_plane.c rename to trunk/drivers/staging/omapdrm/omap_plane.c index dd68d14ce615..bb989d7f026d 100644 --- a/trunk/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/trunk/drivers/staging/omapdrm/omap_plane.c @@ -1,5 +1,5 @@ /* - * drivers/gpu/drm/omapdrm/omap_plane.c + * drivers/staging/omapdrm/omap_plane.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/trunk/drivers/gpu/drm/omapdrm/tcm-sita.c b/trunk/drivers/staging/omapdrm/tcm-sita.c similarity index 100% rename from trunk/drivers/gpu/drm/omapdrm/tcm-sita.c rename to trunk/drivers/staging/omapdrm/tcm-sita.c diff --git a/trunk/drivers/gpu/drm/omapdrm/tcm-sita.h b/trunk/drivers/staging/omapdrm/tcm-sita.h similarity index 100% rename from trunk/drivers/gpu/drm/omapdrm/tcm-sita.h rename to trunk/drivers/staging/omapdrm/tcm-sita.h diff --git a/trunk/drivers/gpu/drm/omapdrm/tcm.h b/trunk/drivers/staging/omapdrm/tcm.h similarity index 99% rename from trunk/drivers/gpu/drm/omapdrm/tcm.h rename to trunk/drivers/staging/omapdrm/tcm.h index a8d5ce47686f..d273e3ee0b4c 100644 --- a/trunk/drivers/gpu/drm/omapdrm/tcm.h +++ b/trunk/drivers/staging/omapdrm/tcm.h @@ -59,8 +59,6 @@ struct tcm { u16 width, height; /* container dimensions */ int lut_id; /* Lookup table identifier */ - unsigned int y_offset; /* offset to use for y coordinates */ - /* 'pvt' structure shall contain any tcm details (attr) along with linked list of allocated areas and mutex for mutually exclusive access to the list. It may also contain copies of width and height to notice diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 09f1a18c1adf..807c7fa689fa 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -21,6 +21,8 @@ source "drivers/gpu/vga/Kconfig" source "drivers/gpu/drm/Kconfig" +source "drivers/gpu/stub/Kconfig" + config VGASTATE tristate default n diff --git a/trunk/include/drm/intel-gtt.h b/trunk/include/drm/intel-gtt.h index b08bdade6002..cf105557fea9 100644 --- a/trunk/include/drm/intel-gtt.h +++ b/trunk/include/drm/intel-gtt.h @@ -3,8 +3,7 @@ #ifndef _DRM_INTEL_GTT_H #define _DRM_INTEL_GTT_H -void intel_gtt_get(size_t *gtt_total, size_t *stolen_size, - phys_addr_t *mappable_base, unsigned long *mappable_end); +void intel_gtt_get(size_t *gtt_total, size_t *stolen_size); int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, struct agp_bridge_data *bridge);