Rev 2332 | Rev 2338 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2332 | Rev 2336 | ||
---|---|---|---|
1 | /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- |
1 | /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- |
2 | */ |
2 | */ |
3 | /* |
3 | /* |
4 | * |
4 | * |
5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
5 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. |
6 | * All Rights Reserved. |
6 | * All Rights Reserved. |
7 | * |
7 | * |
8 | * Permission is hereby granted, free of charge, to any person obtaining a |
8 | * Permission is hereby granted, free of charge, to any person obtaining a |
9 | * copy of this software and associated documentation files (the |
9 | * copy of this software and associated documentation files (the |
10 | * "Software"), to deal in the Software without restriction, including |
10 | * "Software"), to deal in the Software without restriction, including |
11 | * without limitation the rights to use, copy, modify, merge, publish, |
11 | * without limitation the rights to use, copy, modify, merge, publish, |
12 | * distribute, sub license, and/or sell copies of the Software, and to |
12 | * distribute, sub license, and/or sell copies of the Software, and to |
13 | * permit persons to whom the Software is furnished to do so, subject to |
13 | * permit persons to whom the Software is furnished to do so, subject to |
14 | * the following conditions: |
14 | * the following conditions: |
15 | * |
15 | * |
16 | * The above copyright notice and this permission notice (including the |
16 | * The above copyright notice and this permission notice (including the |
17 | * next paragraph) shall be included in all copies or substantial portions |
17 | * next paragraph) shall be included in all copies or substantial portions |
18 | * of the Software. |
18 | * of the Software. |
19 | * |
19 | * |
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
21 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
21 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
22 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
22 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
23 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
23 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
24 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
24 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
26 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
27 | * |
27 | * |
28 | */ |
28 | */ |
29 | 29 | ||
30 | //#include |
30 | //#include |
31 | #include "drmP.h" |
31 | #include "drmP.h" |
32 | #include "drm.h" |
32 | #include "drm.h" |
33 | #include "i915_drm.h" |
33 | #include "i915_drm.h" |
34 | #include "i915_drv.h" |
34 | #include "i915_drv.h" |
35 | #include "intel_drv.h" |
35 | #include "intel_drv.h" |
36 | 36 | ||
37 | 37 | ||
38 | #include |
38 | #include |
39 | #include |
39 | #include |
40 | #include |
40 | #include |
41 | #include |
41 | #include |
42 | #include |
42 | #include |
43 | 43 | ||
44 | #include |
44 | #include |
45 | 45 | ||
46 | #define __read_mostly |
46 | #define __read_mostly |
47 | 47 | ||
48 | 48 | ||
49 | int i915_panel_ignore_lid __read_mostly = 0; |
49 | int i915_panel_ignore_lid __read_mostly = 0; |
50 | 50 | ||
51 | unsigned int i915_powersave __read_mostly = 0; |
51 | unsigned int i915_powersave __read_mostly = 0; |
52 | 52 | ||
53 | unsigned int i915_enable_rc6 __read_mostly = 0; |
53 | unsigned int i915_enable_rc6 __read_mostly = 0; |
54 | 54 | ||
55 | unsigned int i915_enable_fbc __read_mostly = 1; |
55 | unsigned int i915_enable_fbc __read_mostly = 0; |
56 | 56 | ||
57 | unsigned int i915_lvds_downclock __read_mostly = 0; |
57 | unsigned int i915_lvds_downclock __read_mostly = 0; |
58 | 58 | ||
59 | unsigned int i915_panel_use_ssc __read_mostly = 1; |
59 | unsigned int i915_panel_use_ssc __read_mostly = 1; |
60 | 60 | ||
61 | int i915_vbt_sdvo_panel_type __read_mostly = -1; |
61 | int i915_vbt_sdvo_panel_type __read_mostly = -1; |
62 | 62 | ||
63 | #define PCI_VENDOR_ID_INTEL 0x8086 |
63 | #define PCI_VENDOR_ID_INTEL 0x8086 |
64 | 64 | ||
65 | #define INTEL_VGA_DEVICE(id, info) { \ |
65 | #define INTEL_VGA_DEVICE(id, info) { \ |
66 | .class = PCI_CLASS_DISPLAY_VGA << 8, \ |
66 | .class = PCI_CLASS_DISPLAY_VGA << 8, \ |
67 | .class_mask = 0xff0000, \ |
67 | .class_mask = 0xff0000, \ |
68 | .vendor = 0x8086, \ |
68 | .vendor = 0x8086, \ |
69 | .device = id, \ |
69 | .device = id, \ |
70 | .subvendor = PCI_ANY_ID, \ |
70 | .subvendor = PCI_ANY_ID, \ |
71 | .subdevice = PCI_ANY_ID, \ |
71 | .subdevice = PCI_ANY_ID, \ |
72 | .driver_data = (unsigned long) info } |
72 | .driver_data = (unsigned long) info } |
73 | 73 | ||
74 | static const struct intel_device_info intel_sandybridge_d_info = { |
74 | static const struct intel_device_info intel_sandybridge_d_info = { |
75 | .gen = 6, |
75 | .gen = 6, |
76 | .need_gfx_hws = 1, .has_hotplug = 1, |
76 | .need_gfx_hws = 1, .has_hotplug = 1, |
77 | .has_bsd_ring = 1, |
77 | .has_bsd_ring = 1, |
78 | .has_blt_ring = 1, |
78 | .has_blt_ring = 1, |
79 | }; |
79 | }; |
80 | 80 | ||
81 | static const struct intel_device_info intel_sandybridge_m_info = { |
81 | static const struct intel_device_info intel_sandybridge_m_info = { |
82 | .gen = 6, .is_mobile = 1, |
82 | .gen = 6, .is_mobile = 1, |
83 | .need_gfx_hws = 1, .has_hotplug = 1, |
83 | .need_gfx_hws = 1, .has_hotplug = 1, |
84 | .has_fbc = 1, |
84 | .has_fbc = 1, |
85 | .has_bsd_ring = 1, |
85 | .has_bsd_ring = 1, |
86 | .has_blt_ring = 1, |
86 | .has_blt_ring = 1, |
87 | }; |
87 | }; |
88 | 88 | ||
89 | 89 | ||
90 | static const struct pci_device_id pciidlist[] = { /* aka */ |
90 | static const struct pci_device_id pciidlist[] = { /* aka */ |
91 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), |
91 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), |
92 | INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), |
92 | INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), |
93 | INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), |
93 | INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), |
94 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), |
94 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), |
95 | INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), |
95 | INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), |
96 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), |
96 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), |
97 | INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), |
97 | INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), |
98 | {0, 0, 0} |
98 | {0, 0, 0} |
99 | }; |
99 | }; |
100 | 100 | ||
101 | #define INTEL_PCH_DEVICE_ID_MASK 0xff00 |
101 | #define INTEL_PCH_DEVICE_ID_MASK 0xff00 |
102 | #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 |
102 | #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 |
103 | #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 |
103 | #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 |
104 | #define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 |
104 | #define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 |
105 | 105 | ||
106 | void intel_detect_pch (struct drm_device *dev) |
106 | void intel_detect_pch (struct drm_device *dev) |
107 | { |
107 | { |
108 | struct drm_i915_private *dev_priv = dev->dev_private; |
108 | struct drm_i915_private *dev_priv = dev->dev_private; |
109 | struct pci_dev *pch; |
109 | struct pci_dev *pch; |
110 | 110 | ||
111 | /* |
111 | /* |
112 | * The reason to probe ISA bridge instead of Dev31:Fun0 is to |
112 | * The reason to probe ISA bridge instead of Dev31:Fun0 is to |
113 | * make graphics device passthrough work easy for VMM, that only |
113 | * make graphics device passthrough work easy for VMM, that only |
114 | * need to expose ISA bridge to let driver know the real hardware |
114 | * need to expose ISA bridge to let driver know the real hardware |
115 | * underneath. This is a requirement from virtualization team. |
115 | * underneath. This is a requirement from virtualization team. |
116 | */ |
116 | */ |
117 | pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); |
117 | pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); |
118 | if (pch) { |
118 | if (pch) { |
119 | if (pch->vendor == PCI_VENDOR_ID_INTEL) { |
119 | if (pch->vendor == PCI_VENDOR_ID_INTEL) { |
120 | int id; |
120 | int id; |
121 | id = pch->device & INTEL_PCH_DEVICE_ID_MASK; |
121 | id = pch->device & INTEL_PCH_DEVICE_ID_MASK; |
122 | 122 | ||
123 | if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { |
123 | if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { |
124 | dev_priv->pch_type = PCH_IBX; |
124 | dev_priv->pch_type = PCH_IBX; |
125 | DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); |
125 | DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); |
126 | } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { |
126 | } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { |
127 | dev_priv->pch_type = PCH_CPT; |
127 | dev_priv->pch_type = PCH_CPT; |
128 | DRM_DEBUG_KMS("Found CougarPoint PCH\n"); |
128 | DRM_DEBUG_KMS("Found CougarPoint PCH\n"); |
129 | } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { |
129 | } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { |
130 | /* PantherPoint is CPT compatible */ |
130 | /* PantherPoint is CPT compatible */ |
131 | dev_priv->pch_type = PCH_CPT; |
131 | dev_priv->pch_type = PCH_CPT; |
132 | DRM_DEBUG_KMS("Found PatherPoint PCH\n"); |
132 | DRM_DEBUG_KMS("Found PatherPoint PCH\n"); |
133 | } |
133 | } |
134 | } |
134 | } |
135 | } |
135 | } |
136 | } |
136 | } |
137 | 137 | ||
138 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
138 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
139 | { |
139 | { |
140 | int count; |
140 | int count; |
141 | 141 | ||
142 | count = 0; |
142 | count = 0; |
143 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) |
143 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) |
144 | udelay(10); |
144 | udelay(10); |
145 | 145 | ||
146 | I915_WRITE_NOTRACE(FORCEWAKE, 1); |
146 | I915_WRITE_NOTRACE(FORCEWAKE, 1); |
147 | POSTING_READ(FORCEWAKE); |
147 | POSTING_READ(FORCEWAKE); |
148 | 148 | ||
149 | count = 0; |
149 | count = 0; |
150 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0) |
150 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0) |
151 | udelay(10); |
151 | udelay(10); |
152 | } |
152 | } |
153 | 153 | ||
154 | /* |
154 | /* |
155 | * Generally this is called implicitly by the register read function. However, |
155 | * Generally this is called implicitly by the register read function. However, |
156 | * if some sequence requires the GT to not power down then this function should |
156 | * if some sequence requires the GT to not power down then this function should |
157 | * be called at the beginning of the sequence followed by a call to |
157 | * be called at the beginning of the sequence followed by a call to |
158 | * gen6_gt_force_wake_put() at the end of the sequence. |
158 | * gen6_gt_force_wake_put() at the end of the sequence. |
159 | */ |
159 | */ |
160 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
160 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
161 | { |
161 | { |
162 | // WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); |
162 | // WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); |
163 | 163 | ||
164 | /* Forcewake is atomic in case we get in here without the lock */ |
164 | /* Forcewake is atomic in case we get in here without the lock */ |
165 | if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) |
165 | if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) |
166 | __gen6_gt_force_wake_get(dev_priv); |
166 | __gen6_gt_force_wake_get(dev_priv); |
167 | } |
167 | } |
168 | 168 | ||
169 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
169 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
170 | { |
170 | { |
171 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
171 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
172 | POSTING_READ(FORCEWAKE); |
172 | POSTING_READ(FORCEWAKE); |
173 | } |
173 | } |
174 | 174 | ||
175 | /* |
175 | /* |
176 | * see gen6_gt_force_wake_get() |
176 | * see gen6_gt_force_wake_get() |
177 | */ |
177 | */ |
178 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
178 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
179 | { |
179 | { |
180 | // WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); |
180 | // WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); |
181 | 181 | ||
182 | if (atomic_dec_and_test(&dev_priv->forcewake_count)) |
182 | if (atomic_dec_and_test(&dev_priv->forcewake_count)) |
183 | __gen6_gt_force_wake_put(dev_priv); |
183 | __gen6_gt_force_wake_put(dev_priv); |
184 | } |
184 | } |
185 | 185 | ||
186 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
186 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
187 | { |
187 | { |
188 | if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES ) { |
188 | if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES ) { |
189 | int loop = 500; |
189 | int loop = 500; |
190 | u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); |
190 | u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); |
191 | while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { |
191 | while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { |
192 | udelay(10); |
192 | udelay(10); |
193 | fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); |
193 | fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); |
194 | } |
194 | } |
195 | // WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES); |
195 | // WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES); |
196 | dev_priv->gt_fifo_count = fifo; |
196 | dev_priv->gt_fifo_count = fifo; |
197 | } |
197 | } |
198 | dev_priv->gt_fifo_count--; |
198 | dev_priv->gt_fifo_count--; |
199 | } |
199 | } |
200 | 200 | ||
201 | 201 | ||
202 | 202 | ||
203 | 203 | ||
204 | 204 | ||
205 | int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent); |
205 | int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent); |
206 | 206 | ||
207 | int i915_init(void) |
207 | int i915_init(void) |
208 | { |
208 | { |
209 | static pci_dev_t device; |
209 | static pci_dev_t device; |
210 | const struct pci_device_id *ent; |
210 | const struct pci_device_id *ent; |
211 | int err; |
211 | int err; |
212 | 212 | ||
213 | if( init_agp() != 0) |
213 | if( init_agp() != 0) |
214 | { |
214 | { |
215 | DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); |
215 | DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); |
216 | return 0; |
216 | return 0; |
217 | }; |
217 | }; |
218 | 218 | ||
219 | ent = find_pci_device(&device, pciidlist); |
219 | ent = find_pci_device(&device, pciidlist); |
220 | 220 | ||
221 | if( unlikely(ent == NULL) ) |
221 | if( unlikely(ent == NULL) ) |
222 | { |
222 | { |
223 | dbgprintf("device not found\n"); |
223 | dbgprintf("device not found\n"); |
224 | return 0; |
224 | return 0; |
225 | }; |
225 | }; |
226 | 226 | ||
227 | dbgprintf("device %x:%x\n", device.pci_dev.vendor, |
227 | dbgprintf("device %x:%x\n", device.pci_dev.vendor, |
228 | device.pci_dev.device); |
228 | device.pci_dev.device); |
229 | 229 | ||
230 | err = drm_get_dev(&device.pci_dev, ent); |
230 | err = drm_get_dev(&device.pci_dev, ent); |
231 | 231 | ||
232 | return err; |
232 | return err; |
233 | } |
233 | } |
234 | 234 | ||
235 | int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) |
235 | int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) |
236 | { |
236 | { |
237 | static struct drm_device *dev; |
237 | static struct drm_device *dev; |
238 | int ret; |
238 | int ret; |
239 | 239 | ||
240 | ENTER(); |
240 | ENTER(); |
241 | 241 | ||
242 | dev = kzalloc(sizeof(*dev), 0); |
242 | dev = kzalloc(sizeof(*dev), 0); |
243 | if (!dev) |
243 | if (!dev) |
244 | return -ENOMEM; |
244 | return -ENOMEM; |
245 | 245 | ||
246 | // ret = pci_enable_device(pdev); |
246 | // ret = pci_enable_device(pdev); |
247 | // if (ret) |
247 | // if (ret) |
248 | // goto err_g1; |
248 | // goto err_g1; |
249 | 249 | ||
250 | // pci_set_master(pdev); |
250 | // pci_set_master(pdev); |
251 | 251 | ||
252 | // if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { |
252 | // if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { |
253 | // printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
253 | // printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
254 | // goto err_g2; |
254 | // goto err_g2; |
255 | // } |
255 | // } |
256 | 256 | ||
257 | dev->pdev = pdev; |
257 | dev->pdev = pdev; |
258 | dev->pci_device = pdev->device; |
258 | dev->pci_device = pdev->device; |
259 | dev->pci_vendor = pdev->vendor; |
259 | dev->pci_vendor = pdev->vendor; |
260 | 260 | ||
261 | INIT_LIST_HEAD(&dev->filelist); |
261 | INIT_LIST_HEAD(&dev->filelist); |
262 | INIT_LIST_HEAD(&dev->ctxlist); |
262 | INIT_LIST_HEAD(&dev->ctxlist); |
263 | INIT_LIST_HEAD(&dev->vmalist); |
263 | INIT_LIST_HEAD(&dev->vmalist); |
264 | INIT_LIST_HEAD(&dev->maplist); |
264 | INIT_LIST_HEAD(&dev->maplist); |
265 | 265 | ||
266 | spin_lock_init(&dev->count_lock); |
266 | spin_lock_init(&dev->count_lock); |
267 | mutex_init(&dev->struct_mutex); |
267 | mutex_init(&dev->struct_mutex); |
268 | mutex_init(&dev->ctxlist_mutex); |
268 | mutex_init(&dev->ctxlist_mutex); |
269 | 269 | ||
- | 270 | ret = i915_driver_load(dev, ent->driver_data ); |
|
- | 271 | ||
- | 272 | { |
|
- | 273 | struct drm_connector *connector; |
|
- | 274 | struct drm_connector_helper_funcs *connector_funcs; |
|
- | 275 | ||
- | 276 | struct drm_connector *def_connector = NULL; |
|
- | 277 | struct drm_encoder *encoder; |
|
- | 278 | struct drm_crtc *crtc; |
|
- | 279 | ||
- | 280 | struct drm_framebuffer *fb; |
|
- | 281 | char *con_name; |
|
- | 282 | char *enc_name; |
|
- | 283 | ||
- | 284 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
|
- | 285 | { |
|
- | 286 | if( connector->status != connector_status_connected) |
|
- | 287 | continue; |
|
- | 288 | ||
- | 289 | connector_funcs = connector->helper_private; |
|
- | 290 | encoder = connector_funcs->best_encoder(connector); |
|
- | 291 | if( encoder == NULL) |
|
- | 292 | { |
|
- | 293 | dbgprintf("CONNECTOR %x ID: %d no active encoders\n", |
|
- | 294 | connector, connector->base.id); |
|
- | 295 | continue; |
|
- | 296 | } |
|
- | 297 | connector->encoder = encoder; |
|
- | 298 | ||
- | 299 | dbgprintf("CONNECTOR %x ID: %d status %d encoder %x\n crtc %x\n", |
|
- | 300 | connector, connector->base.id, |
|
- | 301 | connector->status, connector->encoder, |
|
- | 302 | encoder->crtc); |
|
- | 303 | ||
- | 304 | def_connector = connector; |
|
- | 305 | crtc = encoder->crtc; |
|
- | 306 | ||
- | 307 | break; |
|
- | 308 | }; |
|
- | 309 | ||
- | 310 | ||
- | 311 | if(crtc == NULL) |
|
- | 312 | { |
|
- | 313 | struct drm_crtc *tmp_crtc; |
|
- | 314 | int crtc_mask = 1; |
|
- | 315 | ||
- | 316 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) |
|
- | 317 | { |
|
- | 318 | if (encoder->possible_crtcs & crtc_mask) |
|
- | 319 | { |
|
- | 320 | crtc = tmp_crtc; |
|
- | 321 | encoder->crtc = crtc; |
|
- | 322 | break; |
|
- | 323 | }; |
|
- | 324 | crtc_mask <<= 1; |
|
- | 325 | }; |
|
- | 326 | ||
- | 327 | if(crtc == NULL) |
|
- | 328 | { |
|
- | 329 | dbgprintf("No CRTC for encoder %d\n", encoder->base.id); |
|
- | 330 | goto out; |
|
- | 331 | } |
|
- | 332 | }; |
|
- | 333 | DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); |
|
- | 334 | ||
- | 335 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 336 | struct drm_fb_helper *fb_helper = &dev_priv->fbdev->helper; |
|
- | 337 | struct drm_display_mode *mode = NULL, *tmpmode; |
|
- | 338 | ||
- | 339 | list_for_each_entry(tmpmode, &connector->modes, head) |
|
- | 340 | { |
|
- | 341 | if( (drm_mode_width(tmpmode) == 1024) && |
|
- | 342 | (drm_mode_height(tmpmode) == 768) && |
|
- | 343 | (drm_mode_vrefresh(tmpmode) == 60) ) |
|
- | 344 | { |
|
- | 345 | mode = tmpmode; |
|
- | 346 | goto do_set; |
|
- | 347 | } |
|
- | 348 | }; |
|
- | 349 | if( (mode == NULL) ) |
|
- | 350 | { |
|
- | 351 | list_for_each_entry(tmpmode, &connector->modes, head) |
|
- | 352 | { |
|
- | 353 | if( (drm_mode_width(tmpmode) == 1024) && |
|
- | 354 | (drm_mode_height(tmpmode) == 768) ) |
|
- | 355 | { |
|
- | 356 | mode = tmpmode; |
|
- | 357 | goto do_set; |
|
- | 358 | } |
|
- | 359 | }; |
|
- | 360 | }; |
|
- | 361 | goto out; |
|
- | 362 | ||
- | 363 | do_set: |
|
- | 364 | { |
|
- | 365 | ||
- | 366 | typedef struct tag_display display_t; |
|
- | 367 | ||
- | 368 | struct tag_display |
|
- | 369 | { |
|
- | 370 | int x; |
|
- | 371 | int y; |
|
- | 372 | int width; |
|
- | 373 | int height; |
|
- | 374 | int bpp; |
|
- | 375 | int vrefresh; |
|
- | 376 | int pitch; |
|
- | 377 | int lfb; |
|
- | 378 | ||
- | 379 | int supported_modes; |
|
- | 380 | struct drm_device *ddev; |
|
- | 381 | struct drm_connector *connector; |
|
- | 382 | struct drm_crtc *crtc; |
|
- | 383 | ||
- | 384 | }; |
|
- | 385 | ||
- | 386 | display_t *rdisplay; |
|
- | 387 | ||
- | 388 | rdisplay = GetDisplay(); |
|
- | 389 | ||
- | 390 | con_name = drm_get_connector_name(connector); |
|
- | 391 | enc_name = drm_get_encoder_name(encoder); |
|
- | 392 | ||
- | 393 | dbgprintf("set mode %d %d connector %s encoder %s\n", |
|
- | 394 | 1024, 768, con_name, enc_name); |
|
- | 395 | ||
- | 396 | fb = fb_helper->fb; |
|
- | 397 | ||
- | 398 | fb->width = 1024; |
|
- | 399 | fb->height = 768; |
|
- | 400 | fb->pitch = ALIGN(1024* ((32 + 7) / 8), 64); |
|
- | 401 | fb->bits_per_pixel = 32; |
|
- | 402 | fb->depth == 24; |
|
- | 403 | ||
- | 404 | crtc->fb = fb; |
|
- | 405 | crtc->enabled = true; |
|
- | 406 | ||
- | 407 | ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb); |
|
- | 408 | ||
- | 409 | if (ret == true) |
|
- | 410 | { |
|
- | 411 | rdisplay->width = fb->width; |
|
- | 412 | rdisplay->height = fb->height; |
|
- | 413 | rdisplay->pitch = fb->pitch; |
|
- | 414 | rdisplay->vrefresh = drm_mode_vrefresh(mode); |
|
- | 415 | ||
- | 416 | sysSetScreen(fb->width, fb->height, fb->pitch); |
|
- | 417 | ||
- | 418 | dbgprintf("new mode %d x %d pitch %d\n", |
|
- | 419 | fb->width, fb->height, fb->pitch); |
|
- | 420 | } |
|
- | 421 | else |
|
- | 422 | DRM_ERROR("failed to set mode %d_%d on crtc %p\n", |
|
- | 423 | fb->width, fb->height, crtc); |
|
- | 424 | }; |
|
- | 425 | }; |
|
- | 426 | ||
270 | - | ||
271 | 427 | out: |
|
272 | ret = i915_driver_load(dev, ent->driver_data ); |
428 | |
273 | // if (ret) |
429 | // if (ret) |
274 | // goto err_g4; |
430 | // goto err_g4; |
275 | 431 | ||
276 | // if( radeon_modeset ) |
432 | // if( radeon_modeset ) |
277 | // init_display_kms(dev->dev_private, &usermode); |
433 | // init_display_kms(dev->dev_private, &usermode); |
278 | // else |
434 | // else |
279 | // init_display(dev->dev_private, &usermode); |
435 | // init_display(dev->dev_private, &usermode); |
280 | 436 | ||
281 | LEAVE(); |
437 | LEAVE(); |
282 | 438 | ||
283 | return 0; |
439 | return 0; |
284 | 440 | ||
285 | err_g4: |
441 | err_g4: |
286 | // drm_put_minor(&dev->primary); |
442 | // drm_put_minor(&dev->primary); |
287 | //err_g3: |
443 | //err_g3: |
288 | // if (drm_core_check_feature(dev, DRIVER_MODESET)) |
444 | // if (drm_core_check_feature(dev, DRIVER_MODESET)) |
289 | // drm_put_minor(&dev->control); |
445 | // drm_put_minor(&dev->control); |
290 | //err_g2: |
446 | //err_g2: |
291 | // pci_disable_device(pdev); |
447 | // pci_disable_device(pdev); |
292 | //err_g1: |
448 | //err_g1: |
293 | free(dev); |
449 | free(dev); |
294 | 450 | ||
295 | LEAVE(); |
451 | LEAVE(); |
296 | 452 | ||
297 | return ret; |
453 | return ret; |
298 | }=>>=>>>>><>><> |
454 | }=><=>=>>=>>>>><>><> |