1 | /* |
2 | * |
3 | * Copyright 2008 (c) Intel Corporation |
4 | * Jesse Barnes <jbarnes@virtuousgeek.org> |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the |
8 | * "Software"), to deal in the Software without restriction, including |
9 | * without limitation the rights to use, copy, modify, merge, publish, |
10 | * distribute, sub license, and/or sell copies of the Software, and to |
11 | * permit persons to whom the Software is furnished to do so, subject to |
12 | * the following conditions: |
13 | * |
14 | * The above copyright notice and this permission notice (including the |
15 | * next paragraph) shall be included in all copies or substantial portions |
16 | * of the Software. |
17 | * |
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
21 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
25 | */ |
26 | |
27 | #include "display/intel_de.h" |
28 | #include "display/intel_gmbus.h" |
29 | #include "display/intel_vga.h" |
30 | |
31 | #include "i915_drv.h" |
32 | #include "i915_reg.h" |
33 | #include "i915_suspend.h" |
34 | #include "intel_pci_config.h" |
35 | |
36 | static void intel_save_swf(struct drm_i915_private *dev_priv) |
37 | { |
38 | int i; |
39 | |
40 | /* Scratch space */ |
41 | if (GRAPHICS_VER(dev_priv) == 2 && IS_MOBILE(dev_priv)) { |
42 | for (i = 0; i < 7; i++) { |
43 | dev_priv->regfile.saveSWF0[i] = intel_de_read(i915: dev_priv, SWF0(i)); |
44 | dev_priv->regfile.saveSWF1[i] = intel_de_read(i915: dev_priv, SWF1(i)); |
45 | } |
46 | for (i = 0; i < 3; i++) |
47 | dev_priv->regfile.saveSWF3[i] = intel_de_read(i915: dev_priv, SWF3(i)); |
48 | } else if (GRAPHICS_VER(dev_priv) == 2) { |
49 | for (i = 0; i < 7; i++) |
50 | dev_priv->regfile.saveSWF1[i] = intel_de_read(i915: dev_priv, SWF1(i)); |
51 | } else if (HAS_GMCH(dev_priv)) { |
52 | for (i = 0; i < 16; i++) { |
53 | dev_priv->regfile.saveSWF0[i] = intel_de_read(i915: dev_priv, SWF0(i)); |
54 | dev_priv->regfile.saveSWF1[i] = intel_de_read(i915: dev_priv, SWF1(i)); |
55 | } |
56 | for (i = 0; i < 3; i++) |
57 | dev_priv->regfile.saveSWF3[i] = intel_de_read(i915: dev_priv, SWF3(i)); |
58 | } |
59 | } |
60 | |
61 | static void intel_restore_swf(struct drm_i915_private *dev_priv) |
62 | { |
63 | int i; |
64 | |
65 | /* Scratch space */ |
66 | if (GRAPHICS_VER(dev_priv) == 2 && IS_MOBILE(dev_priv)) { |
67 | for (i = 0; i < 7; i++) { |
68 | intel_de_write(i915: dev_priv, SWF0(i), val: dev_priv->regfile.saveSWF0[i]); |
69 | intel_de_write(i915: dev_priv, SWF1(i), val: dev_priv->regfile.saveSWF1[i]); |
70 | } |
71 | for (i = 0; i < 3; i++) |
72 | intel_de_write(i915: dev_priv, SWF3(i), val: dev_priv->regfile.saveSWF3[i]); |
73 | } else if (GRAPHICS_VER(dev_priv) == 2) { |
74 | for (i = 0; i < 7; i++) |
75 | intel_de_write(i915: dev_priv, SWF1(i), val: dev_priv->regfile.saveSWF1[i]); |
76 | } else if (HAS_GMCH(dev_priv)) { |
77 | for (i = 0; i < 16; i++) { |
78 | intel_de_write(i915: dev_priv, SWF0(i), val: dev_priv->regfile.saveSWF0[i]); |
79 | intel_de_write(i915: dev_priv, SWF1(i), val: dev_priv->regfile.saveSWF1[i]); |
80 | } |
81 | for (i = 0; i < 3; i++) |
82 | intel_de_write(i915: dev_priv, SWF3(i), val: dev_priv->regfile.saveSWF3[i]); |
83 | } |
84 | } |
85 | |
86 | void i915_save_display(struct drm_i915_private *dev_priv) |
87 | { |
88 | struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); |
89 | |
90 | if (!HAS_DISPLAY(dev_priv)) |
91 | return; |
92 | |
93 | /* Display arbitration control */ |
94 | if (GRAPHICS_VER(dev_priv) <= 4) |
95 | dev_priv->regfile.saveDSPARB = intel_de_read(i915: dev_priv, DSPARB); |
96 | |
97 | if (GRAPHICS_VER(dev_priv) == 4) |
98 | pci_read_config_word(dev: pdev, GCDGMBUS, |
99 | val: &dev_priv->regfile.saveGCDGMBUS); |
100 | |
101 | intel_save_swf(dev_priv); |
102 | } |
103 | |
104 | void i915_restore_display(struct drm_i915_private *dev_priv) |
105 | { |
106 | struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); |
107 | |
108 | if (!HAS_DISPLAY(dev_priv)) |
109 | return; |
110 | |
111 | intel_restore_swf(dev_priv); |
112 | |
113 | if (GRAPHICS_VER(dev_priv) == 4) |
114 | pci_write_config_word(dev: pdev, GCDGMBUS, |
115 | val: dev_priv->regfile.saveGCDGMBUS); |
116 | |
117 | /* Display arbitration */ |
118 | if (GRAPHICS_VER(dev_priv) <= 4) |
119 | intel_de_write(i915: dev_priv, DSPARB, val: dev_priv->regfile.saveDSPARB); |
120 | |
121 | intel_vga_redisable(i915: dev_priv); |
122 | |
123 | intel_gmbus_reset(dev_priv); |
124 | } |
125 | |