blob: b317a8b5fe399710b88123c8522b71ed5fd3bd95 [file] [log] [blame]
Alan Cox5c49fd32011-11-03 18:22:04 +00001/**************************************************************************
2 * Copyright (c) 2007-2011, Intel Corporation.
3 * All Rights Reserved.
4 * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
5 * All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 **************************************************************************/
21
22#include <drm/drmP.h>
23#include <drm/drm.h>
24#include "psb_drm.h"
25#include "psb_drv.h"
26#include "framebuffer.h"
27#include "psb_reg.h"
28#include "psb_intel_reg.h"
29#include "intel_bios.h"
30#include "mid_bios.h"
31#include <drm/drm_pciids.h>
32#include "power.h"
33#include <linux/cpu.h>
34#include <linux/notifier.h>
35#include <linux/spinlock.h>
36#include <linux/pm_runtime.h>
37#include <acpi/video.h>
38
39static int drm_psb_trap_pagefaults;
40
41int drm_psb_no_fb;
42
43static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
44
45MODULE_PARM_DESC(no_fb, "Disable FBdev");
46MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
47module_param_named(no_fb, drm_psb_no_fb, int, 0600);
48module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
49
50
51static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
52 { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
53 { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
54#if defined(CONFIG_DRM_OAKTRAIL)
55 { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
56 { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
57 { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
58 { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
59 { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
60 { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
61 { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
62 { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
63#endif
64#if defined(CONFIG_DRM_CDV)
65 { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
66 { 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
67 { 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
68 { 0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
69 { 0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
70 { 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
71 { 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
72 { 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
73#endif
74 { 0, 0, 0}
75};
76MODULE_DEVICE_TABLE(pci, pciidlist);
77
78/*
79 * Standard IOCTLs.
80 */
81
82#define DRM_IOCTL_PSB_SIZES \
83 DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
84 struct drm_psb_sizes_arg)
85#define DRM_IOCTL_PSB_FUSE_REG \
86 DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t)
87#define DRM_IOCTL_PSB_DC_STATE \
88 DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \
89 struct drm_psb_dc_state_arg)
90#define DRM_IOCTL_PSB_ADB \
91 DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t)
92#define DRM_IOCTL_PSB_MODE_OPERATION \
93 DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \
94 struct drm_psb_mode_operation_arg)
95#define DRM_IOCTL_PSB_STOLEN_MEMORY \
96 DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \
97 struct drm_psb_stolen_memory_arg)
98#define DRM_IOCTL_PSB_REGISTER_RW \
99 DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
100 struct drm_psb_register_rw_arg)
101#define DRM_IOCTL_PSB_DPST \
102 DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
103 uint32_t)
104#define DRM_IOCTL_PSB_GAMMA \
105 DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \
106 struct drm_psb_dpst_lut_arg)
107#define DRM_IOCTL_PSB_DPST_BL \
108 DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \
109 uint32_t)
110#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \
111 DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
112 struct drm_psb_get_pipe_from_crtc_id_arg)
113#define DRM_IOCTL_PSB_GEM_CREATE \
114 DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \
115 struct drm_psb_gem_create)
116#define DRM_IOCTL_PSB_GEM_MMAP \
117 DRM_IOWR(DRM_PSB_GEM_MMAP + DRM_COMMAND_BASE, \
118 struct drm_psb_gem_mmap)
119
120static int psb_sizes_ioctl(struct drm_device *dev, void *data,
121 struct drm_file *file_priv);
122static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
123 struct drm_file *file_priv);
124static int psb_adb_ioctl(struct drm_device *dev, void *data,
125 struct drm_file *file_priv);
126static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
127 struct drm_file *file_priv);
128static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
129 struct drm_file *file_priv);
130static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
131 struct drm_file *file_priv);
132static int psb_dpst_ioctl(struct drm_device *dev, void *data,
133 struct drm_file *file_priv);
134static int psb_gamma_ioctl(struct drm_device *dev, void *data,
135 struct drm_file *file_priv);
136static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
137 struct drm_file *file_priv);
138
139#define PSB_IOCTL_DEF(ioctl, func, flags) \
140 [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
141
142static struct drm_ioctl_desc psb_ioctls[] = {
143 PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
144 PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
145 PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
146 PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
147 DRM_AUTH),
148 PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
149 DRM_AUTH),
150 PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
151 DRM_AUTH),
152 PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
153 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
154 PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
155 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
156 psb_intel_get_pipe_from_crtc_id, 0),
157 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl,
158 DRM_UNLOCKED | DRM_AUTH),
159 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_MMAP, psb_gem_mmap_ioctl,
160 DRM_UNLOCKED | DRM_AUTH),
161};
162
163static void psb_lastclose(struct drm_device *dev)
164{
165 return;
166}
167
168static void psb_do_takedown(struct drm_device *dev)
169{
170 /* FIXME: do we need to clean up the gtt here ? */
171}
172
173static int psb_do_init(struct drm_device *dev)
174{
175 struct drm_psb_private *dev_priv = dev->dev_private;
176 struct psb_gtt *pg = &dev_priv->gtt;
177
178 uint32_t stolen_gtt;
179
180 int ret = -ENOMEM;
181
182 if (pg->mmu_gatt_start & 0x0FFFFFFF) {
183 dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n");
184 ret = -EINVAL;
185 goto out_err;
186 }
187
188
189 stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4;
190 stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT;
191 stolen_gtt =
192 (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages;
193
194 dev_priv->gatt_free_offset = pg->mmu_gatt_start +
195 (stolen_gtt << PAGE_SHIFT) * 1024;
196
197 if (1 || drm_debug) {
198 uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID);
199 uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION);
200 DRM_INFO("SGX core id = 0x%08x\n", core_id);
201 DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n",
202 (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >>
203 _PSB_CC_REVISION_MAJOR_SHIFT,
204 (core_rev & _PSB_CC_REVISION_MINOR_MASK) >>
205 _PSB_CC_REVISION_MINOR_SHIFT);
206 DRM_INFO
207 ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n",
208 (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >>
209 _PSB_CC_REVISION_MAINTENANCE_SHIFT,
210 (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >>
211 _PSB_CC_REVISION_DESIGNER_SHIFT);
212 }
213
214
215 spin_lock_init(&dev_priv->irqmask_lock);
216 mutex_init(&dev_priv->mutex_2d);
217
218 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
219 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
220 PSB_RSGX32(PSB_CR_BIF_BANK1);
221 PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
222 PSB_CR_BIF_CTRL);
223 psb_spank(dev_priv);
224
225 /* mmu_gatt ?? */
226 PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
227 return 0;
228out_err:
229 psb_do_takedown(dev);
230 return ret;
231}
232
233static int psb_driver_unload(struct drm_device *dev)
234{
235 struct drm_psb_private *dev_priv = dev->dev_private;
236
237 /* Kill vblank etc here */
238
239 gma_backlight_exit(dev);
240
241 if (drm_psb_no_fb == 0)
242 psb_modeset_cleanup(dev);
243
244 if (dev_priv) {
245 psb_lid_timer_takedown(dev_priv);
246 gma_intel_opregion_exit(dev);
247
248 if (dev_priv->ops->chip_teardown)
249 dev_priv->ops->chip_teardown(dev);
250 psb_do_takedown(dev);
251
252
253 if (dev_priv->pf_pd) {
254 psb_mmu_free_pagedir(dev_priv->pf_pd);
255 dev_priv->pf_pd = NULL;
256 }
257 if (dev_priv->mmu) {
258 struct psb_gtt *pg = &dev_priv->gtt;
259
260 down_read(&pg->sem);
261 psb_mmu_remove_pfn_sequence(
262 psb_mmu_get_default_pd
263 (dev_priv->mmu),
264 pg->mmu_gatt_start,
265 dev_priv->vram_stolen_size >> PAGE_SHIFT);
266 up_read(&pg->sem);
267 psb_mmu_driver_takedown(dev_priv->mmu);
268 dev_priv->mmu = NULL;
269 }
270 psb_gtt_takedown(dev);
271 if (dev_priv->scratch_page) {
272 __free_page(dev_priv->scratch_page);
273 dev_priv->scratch_page = NULL;
274 }
275 if (dev_priv->vdc_reg) {
276 iounmap(dev_priv->vdc_reg);
277 dev_priv->vdc_reg = NULL;
278 }
279 if (dev_priv->sgx_reg) {
280 iounmap(dev_priv->sgx_reg);
281 dev_priv->sgx_reg = NULL;
282 }
283
284 kfree(dev_priv);
285 dev->dev_private = NULL;
286
287 /*destroy VBT data*/
288 psb_intel_destroy_bios(dev);
289 }
290
291 gma_power_uninit(dev);
292
293 return 0;
294}
295
296
297static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
298{
299 struct drm_psb_private *dev_priv;
300 unsigned long resource_start;
301 struct psb_gtt *pg;
302 unsigned long irqflags;
303 int ret = -ENOMEM;
304 uint32_t tt_pages;
305 struct drm_connector *connector;
306 struct psb_intel_output *psb_intel_output;
307
308 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
309 if (dev_priv == NULL)
310 return -ENOMEM;
311
312 dev_priv->ops = (struct psb_ops *)chipset;
313 dev_priv->dev = dev;
314 dev->dev_private = (void *) dev_priv;
315
316 dev_priv->num_pipe = dev_priv->ops->pipes;
317
318 resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
319
320 dev_priv->vdc_reg =
321 ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE);
322 if (!dev_priv->vdc_reg)
323 goto out_err;
324
325 dev_priv->sgx_reg = ioremap(resource_start + dev_priv->ops->sgx_offset,
326 PSB_SGX_SIZE);
327 if (!dev_priv->sgx_reg)
328 goto out_err;
329
330 ret = dev_priv->ops->chip_setup(dev);
331 if (ret)
332 goto out_err;
333
334 /* Init OSPM support */
335 gma_power_init(dev);
336
337 ret = -ENOMEM;
338
339 dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
340 if (!dev_priv->scratch_page)
341 goto out_err;
342
343 set_pages_uc(dev_priv->scratch_page, 1);
344
345 ret = psb_gtt_init(dev, 0);
346 if (ret)
347 goto out_err;
348
349 dev_priv->mmu = psb_mmu_driver_init((void *)0,
350 drm_psb_trap_pagefaults, 0,
351 dev_priv);
352 if (!dev_priv->mmu)
353 goto out_err;
354
355 pg = &dev_priv->gtt;
356
357 tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
358 (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
359
360
361 dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
362 if (!dev_priv->pf_pd)
363 goto out_err;
364
365 psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
366 psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
367
368 ret = psb_do_init(dev);
369 if (ret)
370 return ret;
371
372 PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
373 PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
374
375/* igd_opregion_init(&dev_priv->opregion_dev); */
376 acpi_video_register();
377 if (dev_priv->lid_state)
378 psb_lid_timer_init(dev_priv);
379
380 ret = drm_vblank_init(dev, dev_priv->num_pipe);
381 if (ret)
382 goto out_err;
383
384 /*
385 * Install interrupt handlers prior to powering off SGX or else we will
386 * crash.
387 */
388 dev_priv->vdc_irq_mask = 0;
389 dev_priv->pipestat[0] = 0;
390 dev_priv->pipestat[1] = 0;
391 dev_priv->pipestat[2] = 0;
392 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
393 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
394 PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
395 PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
396 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
397 if (drm_core_check_feature(dev, DRIVER_MODESET))
398 drm_irq_install(dev);
399
400 dev->vblank_disable_allowed = 1;
401
402 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
403
404 dev->driver->get_vblank_counter = psb_get_vblank_counter;
405
406 if (drm_psb_no_fb == 0) {
407 psb_modeset_init(dev);
408 psb_fbdev_init(dev);
409 drm_kms_helper_poll_init(dev);
410 }
411
412 /* Only add backlight support if we have LVDS output */
413 list_for_each_entry(connector, &dev->mode_config.connector_list,
414 head) {
415 psb_intel_output = to_psb_intel_output(connector);
416
417 switch (psb_intel_output->type) {
418 case INTEL_OUTPUT_LVDS:
419 case INTEL_OUTPUT_MIPI:
420 ret = gma_backlight_init(dev);
421 break;
422 }
423 }
424
425 if (ret)
426 return ret;
427#if 0
428 /*enable runtime pm at last*/
429 pm_runtime_enable(&dev->pdev->dev);
430 pm_runtime_set_active(&dev->pdev->dev);
431#endif
432 /*Intel drm driver load is done, continue doing pvr load*/
433 return 0;
434out_err:
435 psb_driver_unload(dev);
436 return ret;
437}
438
439int psb_driver_device_is_agp(struct drm_device *dev)
440{
441 return 0;
442}
443
444
445static int psb_sizes_ioctl(struct drm_device *dev, void *data,
446 struct drm_file *file_priv)
447{
448 struct drm_psb_private *dev_priv = psb_priv(dev);
449 struct drm_psb_sizes_arg *arg =
450 (struct drm_psb_sizes_arg *) data;
451
452 *arg = dev_priv->sizes;
453 return 0;
454}
455
456static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
457 struct drm_file *file_priv)
458{
459 uint32_t flags;
460 uint32_t obj_id;
461 struct drm_mode_object *obj;
462 struct drm_connector *connector;
463 struct drm_crtc *crtc;
464 struct drm_psb_dc_state_arg *arg = data;
465
466
467 /* Double check MRST case */
468 if (IS_MRST(dev) || IS_MFLD(dev))
469 return -EOPNOTSUPP;
470
471 flags = arg->flags;
472 obj_id = arg->obj_id;
473
474 if (flags & PSB_DC_CRTC_MASK) {
475 obj = drm_mode_object_find(dev, obj_id,
476 DRM_MODE_OBJECT_CRTC);
477 if (!obj) {
478 dev_dbg(dev->dev, "Invalid CRTC object.\n");
479 return -EINVAL;
480 }
481
482 crtc = obj_to_crtc(obj);
483
484 mutex_lock(&dev->mode_config.mutex);
485 if (drm_helper_crtc_in_use(crtc)) {
486 if (flags & PSB_DC_CRTC_SAVE)
487 crtc->funcs->save(crtc);
488 else
489 crtc->funcs->restore(crtc);
490 }
491 mutex_unlock(&dev->mode_config.mutex);
492
493 return 0;
494 } else if (flags & PSB_DC_OUTPUT_MASK) {
495 obj = drm_mode_object_find(dev, obj_id,
496 DRM_MODE_OBJECT_CONNECTOR);
497 if (!obj) {
498 dev_dbg(dev->dev, "Invalid connector id.\n");
499 return -EINVAL;
500 }
501
502 connector = obj_to_connector(obj);
503 if (flags & PSB_DC_OUTPUT_SAVE)
504 connector->funcs->save(connector);
505 else
506 connector->funcs->restore(connector);
507
508 return 0;
509 }
510 return -EINVAL;
511}
512
513static inline void get_brightness(struct backlight_device *bd)
514{
515#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
516 if (bd) {
517 bd->props.brightness = bd->ops->get_brightness(bd);
518 backlight_update_status(bd);
519 }
520#endif
521}
522
523static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
524 struct drm_file *file_priv)
525{
526 struct drm_psb_private *dev_priv = psb_priv(dev);
527 uint32_t *arg = data;
528
529 dev_priv->blc_adj2 = *arg;
530 get_brightness(dev_priv->backlight_device);
531 return 0;
532}
533
534static int psb_adb_ioctl(struct drm_device *dev, void *data,
535 struct drm_file *file_priv)
536{
537 struct drm_psb_private *dev_priv = psb_priv(dev);
538 uint32_t *arg = data;
539
540 dev_priv->blc_adj1 = *arg;
541 get_brightness(dev_priv->backlight_device);
542 return 0;
543}
544
545/* return the current mode to the dpst module */
546static int psb_dpst_ioctl(struct drm_device *dev, void *data,
547 struct drm_file *file_priv)
548{
549 struct drm_psb_private *dev_priv = psb_priv(dev);
550 uint32_t *arg = data;
551 uint32_t x;
552 uint32_t y;
553 uint32_t reg;
554
555 if (!gma_power_begin(dev, 0))
556 return -EIO;
557
558 reg = PSB_RVDC32(PIPEASRC);
559
560 gma_power_end(dev);
561
562 /* horizontal is the left 16 bits */
563 x = reg >> 16;
564 /* vertical is the right 16 bits */
565 y = reg & 0x0000ffff;
566
567 /* the values are the image size minus one */
568 x++;
569 y++;
570
571 *arg = (x << 16) | y;
572
573 return 0;
574}
575static int psb_gamma_ioctl(struct drm_device *dev, void *data,
576 struct drm_file *file_priv)
577{
578 struct drm_psb_dpst_lut_arg *lut_arg = data;
579 struct drm_mode_object *obj;
580 struct drm_crtc *crtc;
581 struct drm_connector *connector;
582 struct psb_intel_crtc *psb_intel_crtc;
583 int i = 0;
584 int32_t obj_id;
585
586 obj_id = lut_arg->output_id;
587 obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
588 if (!obj) {
589 dev_dbg(dev->dev, "Invalid Connector object.\n");
590 return -EINVAL;
591 }
592
593 connector = obj_to_connector(obj);
594 crtc = connector->encoder->crtc;
595 psb_intel_crtc = to_psb_intel_crtc(crtc);
596
597 for (i = 0; i < 256; i++)
598 psb_intel_crtc->lut_adj[i] = lut_arg->lut[i];
599
600 psb_intel_crtc_load_lut(crtc);
601
602 return 0;
603}
604
605static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
606 struct drm_file *file_priv)
607{
608 uint32_t obj_id;
609 uint16_t op;
610 struct drm_mode_modeinfo *umode;
611 struct drm_display_mode *mode = NULL;
612 struct drm_psb_mode_operation_arg *arg;
613 struct drm_mode_object *obj;
614 struct drm_connector *connector;
615 struct drm_framebuffer *drm_fb;
616 struct psb_framebuffer *psb_fb;
617 struct drm_connector_helper_funcs *connector_funcs;
618 int ret = 0;
619 int resp = MODE_OK;
620 struct drm_psb_private *dev_priv = psb_priv(dev);
621
622 arg = (struct drm_psb_mode_operation_arg *)data;
623 obj_id = arg->obj_id;
624 op = arg->operation;
625
626 switch (op) {
627 case PSB_MODE_OPERATION_SET_DC_BASE:
628 obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB);
629 if (!obj) {
630 dev_dbg(dev->dev, "Invalid FB id %d\n", obj_id);
631 return -EINVAL;
632 }
633
634 drm_fb = obj_to_fb(obj);
635 psb_fb = to_psb_fb(drm_fb);
636
637 if (gma_power_begin(dev, 0)) {
638 REG_WRITE(DSPASURF, psb_fb->gtt->offset);
639 REG_READ(DSPASURF);
640 gma_power_end(dev);
641 } else {
642 dev_priv->saveDSPASURF = psb_fb->gtt->offset;
643 }
644
645 return 0;
646 case PSB_MODE_OPERATION_MODE_VALID:
647 umode = &arg->mode;
648
649 mutex_lock(&dev->mode_config.mutex);
650
651 obj = drm_mode_object_find(dev, obj_id,
652 DRM_MODE_OBJECT_CONNECTOR);
653 if (!obj) {
654 ret = -EINVAL;
655 goto mode_op_out;
656 }
657
658 connector = obj_to_connector(obj);
659
660 mode = drm_mode_create(dev);
661 if (!mode) {
662 ret = -ENOMEM;
663 goto mode_op_out;
664 }
665
666 /* drm_crtc_convert_umode(mode, umode); */
667 {
668 mode->clock = umode->clock;
669 mode->hdisplay = umode->hdisplay;
670 mode->hsync_start = umode->hsync_start;
671 mode->hsync_end = umode->hsync_end;
672 mode->htotal = umode->htotal;
673 mode->hskew = umode->hskew;
674 mode->vdisplay = umode->vdisplay;
675 mode->vsync_start = umode->vsync_start;
676 mode->vsync_end = umode->vsync_end;
677 mode->vtotal = umode->vtotal;
678 mode->vscan = umode->vscan;
679 mode->vrefresh = umode->vrefresh;
680 mode->flags = umode->flags;
681 mode->type = umode->type;
682 strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN);
683 mode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
684 }
685
686 connector_funcs = (struct drm_connector_helper_funcs *)
687 connector->helper_private;
688
689 if (connector_funcs->mode_valid) {
690 resp = connector_funcs->mode_valid(connector, mode);
691 arg->data = (void *)resp;
692 }
693
694 /*do some clean up work*/
695 if (mode)
696 drm_mode_destroy(dev, mode);
697mode_op_out:
698 mutex_unlock(&dev->mode_config.mutex);
699 return ret;
700
701 default:
702 dev_dbg(dev->dev, "Unsupported psb mode operation\n");
703 return -EOPNOTSUPP;
704 }
705
706 return 0;
707}
708
709static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
710 struct drm_file *file_priv)
711{
712 struct drm_psb_private *dev_priv = psb_priv(dev);
713 struct drm_psb_stolen_memory_arg *arg = data;
714
715 arg->base = dev_priv->stolen_base;
716 arg->size = dev_priv->vram_stolen_size;
717
718 return 0;
719}
720
721/* FIXME: needs Medfield changes */
722static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
723 struct drm_file *file_priv)
724{
725 struct drm_psb_private *dev_priv = psb_priv(dev);
726 struct drm_psb_register_rw_arg *arg = data;
727 bool usage = arg->b_force_hw_on ? true : false;
728
729 if (arg->display_write_mask != 0) {
730 if (gma_power_begin(dev, usage)) {
731 if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
732 PSB_WVDC32(arg->display.pfit_controls,
733 PFIT_CONTROL);
734 if (arg->display_write_mask &
735 REGRWBITS_PFIT_AUTOSCALE_RATIOS)
736 PSB_WVDC32(arg->display.pfit_autoscale_ratios,
737 PFIT_AUTO_RATIOS);
738 if (arg->display_write_mask &
739 REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
740 PSB_WVDC32(
741 arg->display.pfit_programmed_scale_ratios,
742 PFIT_PGM_RATIOS);
743 if (arg->display_write_mask & REGRWBITS_PIPEASRC)
744 PSB_WVDC32(arg->display.pipeasrc,
745 PIPEASRC);
746 if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
747 PSB_WVDC32(arg->display.pipebsrc,
748 PIPEBSRC);
749 if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
750 PSB_WVDC32(arg->display.vtotal_a,
751 VTOTAL_A);
752 if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
753 PSB_WVDC32(arg->display.vtotal_b,
754 VTOTAL_B);
755 gma_power_end(dev);
756 } else {
757 if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
758 dev_priv->savePFIT_CONTROL =
759 arg->display.pfit_controls;
760 if (arg->display_write_mask &
761 REGRWBITS_PFIT_AUTOSCALE_RATIOS)
762 dev_priv->savePFIT_AUTO_RATIOS =
763 arg->display.pfit_autoscale_ratios;
764 if (arg->display_write_mask &
765 REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
766 dev_priv->savePFIT_PGM_RATIOS =
767 arg->display.pfit_programmed_scale_ratios;
768 if (arg->display_write_mask & REGRWBITS_PIPEASRC)
769 dev_priv->savePIPEASRC = arg->display.pipeasrc;
770 if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
771 dev_priv->savePIPEBSRC = arg->display.pipebsrc;
772 if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
773 dev_priv->saveVTOTAL_A = arg->display.vtotal_a;
774 if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
775 dev_priv->saveVTOTAL_B = arg->display.vtotal_b;
776 }
777 }
778
779 if (arg->display_read_mask != 0) {
780 if (gma_power_begin(dev, usage)) {
781 if (arg->display_read_mask &
782 REGRWBITS_PFIT_CONTROLS)
783 arg->display.pfit_controls =
784 PSB_RVDC32(PFIT_CONTROL);
785 if (arg->display_read_mask &
786 REGRWBITS_PFIT_AUTOSCALE_RATIOS)
787 arg->display.pfit_autoscale_ratios =
788 PSB_RVDC32(PFIT_AUTO_RATIOS);
789 if (arg->display_read_mask &
790 REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
791 arg->display.pfit_programmed_scale_ratios =
792 PSB_RVDC32(PFIT_PGM_RATIOS);
793 if (arg->display_read_mask & REGRWBITS_PIPEASRC)
794 arg->display.pipeasrc = PSB_RVDC32(PIPEASRC);
795 if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
796 arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC);
797 if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
798 arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
799 if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
800 arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
801 gma_power_end(dev);
802 } else {
803 if (arg->display_read_mask &
804 REGRWBITS_PFIT_CONTROLS)
805 arg->display.pfit_controls =
806 dev_priv->savePFIT_CONTROL;
807 if (arg->display_read_mask &
808 REGRWBITS_PFIT_AUTOSCALE_RATIOS)
809 arg->display.pfit_autoscale_ratios =
810 dev_priv->savePFIT_AUTO_RATIOS;
811 if (arg->display_read_mask &
812 REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
813 arg->display.pfit_programmed_scale_ratios =
814 dev_priv->savePFIT_PGM_RATIOS;
815 if (arg->display_read_mask & REGRWBITS_PIPEASRC)
816 arg->display.pipeasrc = dev_priv->savePIPEASRC;
817 if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
818 arg->display.pipebsrc = dev_priv->savePIPEBSRC;
819 if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
820 arg->display.vtotal_a = dev_priv->saveVTOTAL_A;
821 if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
822 arg->display.vtotal_b = dev_priv->saveVTOTAL_B;
823 }
824 }
825
826 if (arg->overlay_write_mask != 0) {
827 if (gma_power_begin(dev, usage)) {
828 if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
829 PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
830 PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
831 PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3);
832 PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2);
833 PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1);
834 PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0);
835 }
836 if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
837 PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5);
838 PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4);
839 PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3);
840 PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2);
841 PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1);
842 PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0);
843 }
844
845 if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) {
846 PSB_WVDC32(arg->overlay.OVADD, OV_OVADD);
847
848 if (arg->overlay.b_wait_vblank) {
849 /* Wait for 20ms.*/
850 unsigned long vblank_timeout = jiffies
851 + HZ/50;
852 uint32_t temp;
853 while (time_before_eq(jiffies,
854 vblank_timeout)) {
855 temp = PSB_RVDC32(OV_DOVASTA);
856 if ((temp & (0x1 << 31)) != 0)
857 break;
858 cpu_relax();
859 }
860 }
861 }
862 if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) {
863 PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD);
864 if (arg->overlay.b_wait_vblank) {
865 /* Wait for 20ms.*/
866 unsigned long vblank_timeout =
867 jiffies + HZ/50;
868 uint32_t temp;
869 while (time_before_eq(jiffies,
870 vblank_timeout)) {
871 temp = PSB_RVDC32(OVC_DOVCSTA);
872 if ((temp & (0x1 << 31)) != 0)
873 break;
874 cpu_relax();
875 }
876 }
877 }
878 gma_power_end(dev);
879 } else {
880 if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
881 dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5;
882 dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4;
883 dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3;
884 dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2;
885 dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1;
886 dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0;
887 }
888 if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
889 dev_priv->saveOVC_OGAMC5 = arg->overlay.OGAMC5;
890 dev_priv->saveOVC_OGAMC4 = arg->overlay.OGAMC4;
891 dev_priv->saveOVC_OGAMC3 = arg->overlay.OGAMC3;
892 dev_priv->saveOVC_OGAMC2 = arg->overlay.OGAMC2;
893 dev_priv->saveOVC_OGAMC1 = arg->overlay.OGAMC1;
894 dev_priv->saveOVC_OGAMC0 = arg->overlay.OGAMC0;
895 }
896 if (arg->overlay_write_mask & OV_REGRWBITS_OVADD)
897 dev_priv->saveOV_OVADD = arg->overlay.OVADD;
898 if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD)
899 dev_priv->saveOVC_OVADD = arg->overlay.OVADD;
900 }
901 }
902
903 if (arg->overlay_read_mask != 0) {
904 if (gma_power_begin(dev, usage)) {
905 if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
906 arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
907 arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
908 arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3);
909 arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2);
910 arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1);
911 arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0);
912 }
913 if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
914 arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5);
915 arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4);
916 arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3);
917 arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2);
918 arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1);
919 arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0);
920 }
921 if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
922 arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
923 if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
924 arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD);
925 gma_power_end(dev);
926 } else {
927 if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
928 arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5;
929 arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4;
930 arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3;
931 arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2;
932 arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1;
933 arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0;
934 }
935 if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
936 arg->overlay.OGAMC5 = dev_priv->saveOVC_OGAMC5;
937 arg->overlay.OGAMC4 = dev_priv->saveOVC_OGAMC4;
938 arg->overlay.OGAMC3 = dev_priv->saveOVC_OGAMC3;
939 arg->overlay.OGAMC2 = dev_priv->saveOVC_OGAMC2;
940 arg->overlay.OGAMC1 = dev_priv->saveOVC_OGAMC1;
941 arg->overlay.OGAMC0 = dev_priv->saveOVC_OGAMC0;
942 }
943 if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
944 arg->overlay.OVADD = dev_priv->saveOV_OVADD;
945 if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
946 arg->overlay.OVADD = dev_priv->saveOVC_OVADD;
947 }
948 }
949
950 if (arg->sprite_enable_mask != 0) {
951 if (gma_power_begin(dev, usage)) {
952 PSB_WVDC32(0x1F3E, DSPARB);
953 PSB_WVDC32(arg->sprite.dspa_control
954 | PSB_RVDC32(DSPACNTR), DSPACNTR);
955 PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL);
956 PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK);
957 PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF);
958 PSB_RVDC32(DSPASURF);
959 PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR);
960 PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE);
961 PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS);
962 PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF);
963 PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
964 PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
965 PSB_RVDC32(DSPCSURF);
966 gma_power_end(dev);
967 }
968 }
969
970 if (arg->sprite_disable_mask != 0) {
971 if (gma_power_begin(dev, usage)) {
972 PSB_WVDC32(0x3F3E, DSPARB);
973 PSB_WVDC32(0x0, DSPCCNTR);
974 PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
975 PSB_RVDC32(DSPCSURF);
976 gma_power_end(dev);
977 }
978 }
979
980 if (arg->subpicture_enable_mask != 0) {
981 if (gma_power_begin(dev, usage)) {
982 uint32_t temp;
983 if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) {
984 temp = PSB_RVDC32(DSPACNTR);
985 temp &= ~DISPPLANE_PIXFORMAT_MASK;
986 temp &= ~DISPPLANE_BOTTOM;
987 temp |= DISPPLANE_32BPP;
988 PSB_WVDC32(temp, DSPACNTR);
989
990 temp = PSB_RVDC32(DSPABASE);
991 PSB_WVDC32(temp, DSPABASE);
992 PSB_RVDC32(DSPABASE);
993 temp = PSB_RVDC32(DSPASURF);
994 PSB_WVDC32(temp, DSPASURF);
995 PSB_RVDC32(DSPASURF);
996 }
997 if (arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR) {
998 temp = PSB_RVDC32(DSPBCNTR);
999 temp &= ~DISPPLANE_PIXFORMAT_MASK;
1000 temp &= ~DISPPLANE_BOTTOM;
1001 temp |= DISPPLANE_32BPP;
1002 PSB_WVDC32(temp, DSPBCNTR);
1003
1004 temp = PSB_RVDC32(DSPBBASE);
1005 PSB_WVDC32(temp, DSPBBASE);
1006 PSB_RVDC32(DSPBBASE);
1007 temp = PSB_RVDC32(DSPBSURF);
1008 PSB_WVDC32(temp, DSPBSURF);
1009 PSB_RVDC32(DSPBSURF);
1010 }
1011 if (arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR) {
1012 temp = PSB_RVDC32(DSPCCNTR);
1013 temp &= ~DISPPLANE_PIXFORMAT_MASK;
1014 temp &= ~DISPPLANE_BOTTOM;
1015 temp |= DISPPLANE_32BPP;
1016 PSB_WVDC32(temp, DSPCCNTR);
1017
1018 temp = PSB_RVDC32(DSPCBASE);
1019 PSB_WVDC32(temp, DSPCBASE);
1020 PSB_RVDC32(DSPCBASE);
1021 temp = PSB_RVDC32(DSPCSURF);
1022 PSB_WVDC32(temp, DSPCSURF);
1023 PSB_RVDC32(DSPCSURF);
1024 }
1025 gma_power_end(dev);
1026 }
1027 }
1028
1029 if (arg->subpicture_disable_mask != 0) {
1030 if (gma_power_begin(dev, usage)) {
1031 uint32_t temp;
1032 if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) {
1033 temp = PSB_RVDC32(DSPACNTR);
1034 temp &= ~DISPPLANE_PIXFORMAT_MASK;
1035 temp |= DISPPLANE_32BPP_NO_ALPHA;
1036 PSB_WVDC32(temp, DSPACNTR);
1037
1038 temp = PSB_RVDC32(DSPABASE);
1039 PSB_WVDC32(temp, DSPABASE);
1040 PSB_RVDC32(DSPABASE);
1041 temp = PSB_RVDC32(DSPASURF);
1042 PSB_WVDC32(temp, DSPASURF);
1043 PSB_RVDC32(DSPASURF);
1044 }
1045 if (arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR) {
1046 temp = PSB_RVDC32(DSPBCNTR);
1047 temp &= ~DISPPLANE_PIXFORMAT_MASK;
1048 temp |= DISPPLANE_32BPP_NO_ALPHA;
1049 PSB_WVDC32(temp, DSPBCNTR);
1050
1051 temp = PSB_RVDC32(DSPBBASE);
1052 PSB_WVDC32(temp, DSPBBASE);
1053 PSB_RVDC32(DSPBBASE);
1054 temp = PSB_RVDC32(DSPBSURF);
1055 PSB_WVDC32(temp, DSPBSURF);
1056 PSB_RVDC32(DSPBSURF);
1057 }
1058 if (arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR) {
1059 temp = PSB_RVDC32(DSPCCNTR);
1060 temp &= ~DISPPLANE_PIXFORMAT_MASK;
1061 temp |= DISPPLANE_32BPP_NO_ALPHA;
1062 PSB_WVDC32(temp, DSPCCNTR);
1063
1064 temp = PSB_RVDC32(DSPCBASE);
1065 PSB_WVDC32(temp, DSPCBASE);
1066 PSB_RVDC32(DSPCBASE);
1067 temp = PSB_RVDC32(DSPCSURF);
1068 PSB_WVDC32(temp, DSPCSURF);
1069 PSB_RVDC32(DSPCSURF);
1070 }
1071 gma_power_end(dev);
1072 }
1073 }
1074
1075 return 0;
1076}
1077
1078static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
1079{
1080 return 0;
1081}
1082
1083static void psb_driver_close(struct drm_device *dev, struct drm_file *priv)
1084{
1085}
1086
1087static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
1088 unsigned long arg)
1089{
1090 struct drm_file *file_priv = filp->private_data;
1091 struct drm_device *dev = file_priv->minor->dev;
1092 struct drm_psb_private *dev_priv = dev->dev_private;
1093 static unsigned int runtime_allowed;
1094
1095 if (runtime_allowed == 1 && dev_priv->is_lvds_on) {
1096 runtime_allowed++;
1097 pm_runtime_allow(&dev->pdev->dev);
1098 dev_priv->rpm_enabled = 1;
1099 }
1100 return drm_ioctl(filp, cmd, arg);
1101 /* FIXME: do we need to wrap the other side of this */
1102}
1103
1104
1105/* When a client dies:
1106 * - Check for and clean up flipped page state
1107 */
1108void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
1109{
1110}
1111
1112static void psb_remove(struct pci_dev *pdev)
1113{
1114 struct drm_device *dev = pci_get_drvdata(pdev);
1115 drm_put_dev(dev);
1116}
1117
1118static const struct dev_pm_ops psb_pm_ops = {
1119 .resume = gma_power_resume,
1120 .suspend = gma_power_suspend,
1121 .runtime_suspend = psb_runtime_suspend,
1122 .runtime_resume = psb_runtime_resume,
1123 .runtime_idle = psb_runtime_idle,
1124};
1125
1126static struct vm_operations_struct psb_gem_vm_ops = {
1127 .fault = psb_gem_fault,
1128 .open = drm_gem_vm_open,
1129 .close = drm_gem_vm_close,
1130};
1131
1132static struct drm_driver driver = {
1133 .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
1134 DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM ,
1135 .load = psb_driver_load,
1136 .unload = psb_driver_unload,
1137
1138 .ioctls = psb_ioctls,
1139 .num_ioctls = DRM_ARRAY_SIZE(psb_ioctls),
1140 .device_is_agp = psb_driver_device_is_agp,
1141 .irq_preinstall = psb_irq_preinstall,
1142 .irq_postinstall = psb_irq_postinstall,
1143 .irq_uninstall = psb_irq_uninstall,
1144 .irq_handler = psb_irq_handler,
1145 .enable_vblank = psb_enable_vblank,
1146 .disable_vblank = psb_disable_vblank,
1147 .get_vblank_counter = psb_get_vblank_counter,
1148 .lastclose = psb_lastclose,
1149 .open = psb_driver_open,
1150 .preclose = psb_driver_preclose,
1151 .postclose = psb_driver_close,
1152 .reclaim_buffers = drm_core_reclaim_buffers,
1153
1154 .gem_init_object = psb_gem_init_object,
1155 .gem_free_object = psb_gem_free_object,
1156 .gem_vm_ops = &psb_gem_vm_ops,
1157 .dumb_create = psb_gem_dumb_create,
1158 .dumb_map_offset = psb_gem_dumb_map_gtt,
1159 .dumb_destroy = psb_gem_dumb_destroy,
1160
1161 .fops = {
1162 .owner = THIS_MODULE,
1163 .open = drm_open,
1164 .release = drm_release,
1165 .unlocked_ioctl = psb_unlocked_ioctl,
1166 .mmap = drm_gem_mmap,
1167 .poll = drm_poll,
1168 .fasync = drm_fasync,
1169 .read = drm_read,
1170 },
1171 .name = DRIVER_NAME,
1172 .desc = DRIVER_DESC,
1173 .date = PSB_DRM_DRIVER_DATE,
1174 .major = PSB_DRM_DRIVER_MAJOR,
1175 .minor = PSB_DRM_DRIVER_MINOR,
1176 .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL
1177};
1178
1179static struct pci_driver psb_pci_driver = {
1180 .name = DRIVER_NAME,
1181 .id_table = pciidlist,
1182 .probe = psb_probe,
1183 .remove = psb_remove,
1184 .driver.pm = &psb_pm_ops,
1185};
1186
1187static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1188{
1189 /* MLD Added this from Inaky's patch */
1190 if (pci_enable_msi(pdev))
1191 dev_warn(&pdev->dev, "Enable MSI failed!\n");
1192 return drm_get_pci_dev(pdev, ent, &driver);
1193}
1194
1195static int __init psb_init(void)
1196{
1197 return drm_pci_init(&driver, &psb_pci_driver);
1198}
1199
1200static void __exit psb_exit(void)
1201{
1202 drm_pci_exit(&driver, &psb_pci_driver);
1203}
1204
1205late_initcall(psb_init);
1206module_exit(psb_exit);
1207
1208MODULE_AUTHOR("Alan Cox <alan@linux.intel.com> and others");
1209MODULE_DESCRIPTION(DRIVER_DESC);
1210MODULE_LICENSE("GPL");