aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-04-17 01:18:32 -0400
committerDave Airlie <airlied@redhat.com>2013-04-17 01:18:32 -0400
commit9f7bc6acf78af238a0b8ee0bb86ab62f1fc4f51f (patch)
treeb1083136e21199935c9811bc9f41905f3c5f0499
parentf18353eee7570412adca210b4968ecf2783754ba (diff)
parent1611f8457768716ba2397e0cdcc92c863cf9b58b (diff)
Merge branch 'gma500-next' of git://github.com/patjak/drm-gma500 into drm-next
Patrik writes: I haven't had much review or testing on other platforms than Poulsbo but at least the following Cedarview bug has been squashed and no regressions reported: https://bugs.freedesktop.org/show_bug.cgi?id=58527 * 'gma500-next' of git://github.com/patjak/drm-gma500: drm/gma500: Add debugging info to psb_gtt_restore() drm/gma500: Check connector status before restoring sdvo gma500:fix build failure for 3.9-rc5 drm/gma500: Fix hibernation problems on sdvo encoders drm/gma500: Add hooks for hibernation drm/gma500: Activate the gtt rebuild on suspend/resume drm/gma500: Add support for rebuilding the gtt drm/gma500: Change fb name so pm-utils doesn't apply quirks gma500: Make VGA and HDMI connector hotpluggable drm/gma500: Clean up various defines drm/gma500: Remove unnecessary function exposure drm/gma500: Type clock limits directly into array and remove defines drm/gma500: Calculate clock in one function instead of three identical drm/gma500: Remove unused i8xx clock limits gma500: medfield: Fix possible NULL pointer dereference drivers: gpu: drm: gma500: Replaced calls kzalloc & memcpy with kmemdup gma500: remove unused drm_psb_no_fb
-rw-r--r--drivers/gpu/drm/gma500/Kconfig13
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c1
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c1
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c2
-rw-r--r--drivers/gpu/drm/gma500/gtt.c52
-rw-r--r--drivers/gpu/drm/gma500/gtt.h2
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c3
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.h6
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.c7
-rw-r--r--drivers/gpu/drm/gma500/power.c17
-rw-r--r--drivers/gpu/drm/gma500/power.h3
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c3
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h1
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.c154
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.h3
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h8
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_reg.h1
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c33
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.h6
19 files changed, 154 insertions, 162 deletions
diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 1188f0fe7e4f..1f6e2dfaaeae 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -2,10 +2,15 @@ config DRM_GMA500
2 tristate "Intel GMA5/600 KMS Framebuffer" 2 tristate "Intel GMA5/600 KMS Framebuffer"
3 depends on DRM && PCI && X86 3 depends on DRM && PCI && X86
4 select FB_CFB_COPYAREA 4 select FB_CFB_COPYAREA
5 select FB_CFB_FILLRECT 5 select FB_CFB_FILLRECT
6 select FB_CFB_IMAGEBLIT 6 select FB_CFB_IMAGEBLIT
7 select DRM_KMS_HELPER 7 select DRM_KMS_HELPER
8 select DRM_TTM 8 select DRM_TTM
9 # GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
10 select ACPI_VIDEO if ACPI
11 select BACKLIGHT_CLASS_DEVICE if ACPI
12 select VIDEO_OUTPUT_CONTROL if ACPI
13 select INPUT if ACPI
9 help 14 help
10 Say yes for an experimental 2D KMS framebuffer driver for the 15 Say yes for an experimental 2D KMS framebuffer driver for the
11 Intel GMA500 ('Poulsbo') and other Intel IMG based graphics 16 Intel GMA500 ('Poulsbo') and other Intel IMG based graphics
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 8c175345d85c..7b8386fc3024 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -276,6 +276,7 @@ void cdv_intel_crt_init(struct drm_device *dev,
276 goto failed_connector; 276 goto failed_connector;
277 277
278 connector = &psb_intel_connector->base; 278 connector = &psb_intel_connector->base;
279 connector->polled = DRM_CONNECTOR_POLL_HPD;
279 drm_connector_init(dev, connector, 280 drm_connector_init(dev, connector,
280 &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); 281 &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
281 282
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index e223b500022e..464153d9d2df 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -319,6 +319,7 @@ void cdv_hdmi_init(struct drm_device *dev,
319 goto err_priv; 319 goto err_priv;
320 320
321 connector = &psb_intel_connector->base; 321 connector = &psb_intel_connector->base;
322 connector->polled = DRM_CONNECTOR_POLL_HPD;
322 encoder = &psb_intel_encoder->base; 323 encoder = &psb_intel_encoder->base;
323 drm_connector_init(dev, connector, 324 drm_connector_init(dev, connector,
324 &cdv_hdmi_connector_funcs, 325 &cdv_hdmi_connector_funcs,
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 2590cac84257..31ac392b84ea 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -431,7 +431,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
431 fbdev->psb_fb_helper.fbdev = info; 431 fbdev->psb_fb_helper.fbdev = info;
432 432
433 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); 433 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
434 strcpy(info->fix.id, "psbfb"); 434 strcpy(info->fix.id, "psbdrmfb");
435 435
436 info->flags = FBINFO_DEFAULT; 436 info->flags = FBINFO_DEFAULT;
437 if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */ 437 if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 054e26e769ec..1f82183536a3 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -80,7 +80,8 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
80 * the GTT. This is protected via the gtt mutex which the caller 80 * the GTT. This is protected via the gtt mutex which the caller
81 * must hold. 81 * must hold.
82 */ 82 */
83static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) 83static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,
84 int resume)
84{ 85{
85 u32 __iomem *gtt_slot; 86 u32 __iomem *gtt_slot;
86 u32 pte; 87 u32 pte;
@@ -97,8 +98,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
97 gtt_slot = psb_gtt_entry(dev, r); 98 gtt_slot = psb_gtt_entry(dev, r);
98 pages = r->pages; 99 pages = r->pages;
99 100
100 /* Make sure changes are visible to the GPU */ 101 if (!resume) {
101 set_pages_array_wc(pages, r->npage); 102 /* Make sure changes are visible to the GPU */
103 set_pages_array_wc(pages, r->npage);
104 }
102 105
103 /* Write our page entries into the GTT itself */ 106 /* Write our page entries into the GTT itself */
104 for (i = r->roll; i < r->npage; i++) { 107 for (i = r->roll; i < r->npage; i++) {
@@ -269,7 +272,7 @@ int psb_gtt_pin(struct gtt_range *gt)
269 ret = psb_gtt_attach_pages(gt); 272 ret = psb_gtt_attach_pages(gt);
270 if (ret < 0) 273 if (ret < 0)
271 goto out; 274 goto out;
272 ret = psb_gtt_insert(dev, gt); 275 ret = psb_gtt_insert(dev, gt, 0);
273 if (ret < 0) { 276 if (ret < 0) {
274 psb_gtt_detach_pages(gt); 277 psb_gtt_detach_pages(gt);
275 goto out; 278 goto out;
@@ -421,9 +424,11 @@ int psb_gtt_init(struct drm_device *dev, int resume)
421 int ret = 0; 424 int ret = 0;
422 uint32_t pte; 425 uint32_t pte;
423 426
424 mutex_init(&dev_priv->gtt_mutex); 427 if (!resume) {
428 mutex_init(&dev_priv->gtt_mutex);
429 psb_gtt_alloc(dev);
430 }
425 431
426 psb_gtt_alloc(dev);
427 pg = &dev_priv->gtt; 432 pg = &dev_priv->gtt;
428 433
429 /* Enable the GTT */ 434 /* Enable the GTT */
@@ -505,7 +510,8 @@ int psb_gtt_init(struct drm_device *dev, int resume)
505 /* 510 /*
506 * Map the GTT and the stolen memory area 511 * Map the GTT and the stolen memory area
507 */ 512 */
508 dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, 513 if (!resume)
514 dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
509 gtt_pages << PAGE_SHIFT); 515 gtt_pages << PAGE_SHIFT);
510 if (!dev_priv->gtt_map) { 516 if (!dev_priv->gtt_map) {
511 dev_err(dev->dev, "Failure to map gtt.\n"); 517 dev_err(dev->dev, "Failure to map gtt.\n");
@@ -513,7 +519,9 @@ int psb_gtt_init(struct drm_device *dev, int resume)
513 goto out_err; 519 goto out_err;
514 } 520 }
515 521
516 dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); 522 if (!resume)
523 dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base,
524 stolen_size);
517 if (!dev_priv->vram_addr) { 525 if (!dev_priv->vram_addr) {
518 dev_err(dev->dev, "Failure to map stolen base.\n"); 526 dev_err(dev->dev, "Failure to map stolen base.\n");
519 ret = -ENOMEM; 527 ret = -ENOMEM;
@@ -549,3 +557,31 @@ out_err:
549 psb_gtt_takedown(dev); 557 psb_gtt_takedown(dev);
550 return ret; 558 return ret;
551} 559}
560
561int psb_gtt_restore(struct drm_device *dev)
562{
563 struct drm_psb_private *dev_priv = dev->dev_private;
564 struct resource *r = dev_priv->gtt_mem->child;
565 struct gtt_range *range;
566 unsigned int restored = 0, total = 0, size = 0;
567
568 /* On resume, the gtt_mutex is already initialized */
569 mutex_lock(&dev_priv->gtt_mutex);
570 psb_gtt_init(dev, 1);
571
572 while (r != NULL) {
573 range = container_of(r, struct gtt_range, resource);
574 if (range->pages) {
575 psb_gtt_insert(dev, range, 1);
576 size += range->resource.end - range->resource.start;
577 restored++;
578 }
579 r = r->sibling;
580 total++;
581 }
582 mutex_unlock(&dev_priv->gtt_mutex);
583 DRM_DEBUG_DRIVER("Restored %u of %u gtt ranges (%u KB)", restored,
584 total, (size / 1024));
585
586 return 0;
587}
diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h
index aa1742387f5a..6191d10acf33 100644
--- a/drivers/gpu/drm/gma500/gtt.h
+++ b/drivers/gpu/drm/gma500/gtt.h
@@ -60,5 +60,5 @@ extern int psb_gtt_pin(struct gtt_range *gt);
60extern void psb_gtt_unpin(struct gtt_range *gt); 60extern void psb_gtt_unpin(struct gtt_range *gt);
61extern void psb_gtt_roll(struct drm_device *dev, 61extern void psb_gtt_roll(struct drm_device *dev,
62 struct gtt_range *gt, int roll); 62 struct gtt_range *gt, int roll);
63 63extern int psb_gtt_restore(struct drm_device *dev);
64#endif 64#endif
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c
index 403fffb03abd..d3497348c4d5 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -218,12 +218,11 @@ static void parse_backlight_data(struct drm_psb_private *dev_priv,
218 bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT); 218 bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
219 vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type; 219 vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
220 220
221 lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL); 221 lvds_bl = kmemdup(vbt_lvds_bl, sizeof(*vbt_lvds_bl), GFP_KERNEL);
222 if (!lvds_bl) { 222 if (!lvds_bl) {
223 dev_err(dev_priv->dev->dev, "out of memory for backlight data\n"); 223 dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
224 return; 224 return;
225 } 225 }
226 memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
227 dev_priv->lvds_bl = lvds_bl; 226 dev_priv->lvds_bl = lvds_bl;
228} 227}
229 228
diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h
index c6267c98c9e7..978ae4b25e82 100644
--- a/drivers/gpu/drm/gma500/intel_bios.h
+++ b/drivers/gpu/drm/gma500/intel_bios.h
@@ -19,8 +19,8 @@
19 * 19 *
20 */ 20 */
21 21
22#ifndef _I830_BIOS_H_ 22#ifndef _INTEL_BIOS_H_
23#define _I830_BIOS_H_ 23#define _INTEL_BIOS_H_
24 24
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include <drm/drm_dp_helper.h> 26#include <drm/drm_dp_helper.h>
@@ -618,4 +618,4 @@ extern void psb_intel_destroy_bios(struct drm_device *dev);
618#define PORT_IDPC 8 618#define PORT_IDPC 8
619#define PORT_IDPD 9 619#define PORT_IDPD 9
620 620
621#endif /* _I830_BIOS_H_ */ 621#endif /* _INTEL_BIOS_H_ */
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
index 2d4ab48f07a2..3abf8315f57c 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
@@ -92,8 +92,8 @@ void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe)
92{ 92{
93 struct mdfld_dsi_pkg_sender *sender = 93 struct mdfld_dsi_pkg_sender *sender =
94 mdfld_dsi_get_pkg_sender(dsi_config); 94 mdfld_dsi_get_pkg_sender(dsi_config);
95 struct drm_device *dev = sender->dev; 95 struct drm_device *dev;
96 struct drm_psb_private *dev_priv = dev->dev_private; 96 struct drm_psb_private *dev_priv;
97 u32 gen_ctrl_val; 97 u32 gen_ctrl_val;
98 98
99 if (!sender) { 99 if (!sender) {
@@ -101,6 +101,9 @@ void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe)
101 return; 101 return;
102 } 102 }
103 103
104 dev = sender->dev;
105 dev_priv = dev->dev_private;
106
104 /* Set default display backlight value to 85% (0xd8)*/ 107 /* Set default display backlight value to 85% (0xd8)*/
105 mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1, 108 mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1,
106 true); 109 true);
diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c
index 889b854751da..b6b135fcd59c 100644
--- a/drivers/gpu/drm/gma500/power.c
+++ b/drivers/gpu/drm/gma500/power.c
@@ -110,6 +110,8 @@ static void gma_resume_display(struct pci_dev *pdev)
110 PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); 110 PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
111 pci_write_config_word(pdev, PSB_GMCH_CTRL, 111 pci_write_config_word(pdev, PSB_GMCH_CTRL,
112 dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); 112 dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
113
114 psb_gtt_restore(dev); /* Rebuild our GTT mappings */
113 dev_priv->ops->restore_regs(dev); 115 dev_priv->ops->restore_regs(dev);
114} 116}
115 117
@@ -313,3 +315,18 @@ int psb_runtime_idle(struct device *dev)
313 else 315 else
314 return 1; 316 return 1;
315} 317}
318
319int gma_power_thaw(struct device *_dev)
320{
321 return gma_power_resume(_dev);
322}
323
324int gma_power_freeze(struct device *_dev)
325{
326 return gma_power_suspend(_dev);
327}
328
329int gma_power_restore(struct device *_dev)
330{
331 return gma_power_resume(_dev);
332}
diff --git a/drivers/gpu/drm/gma500/power.h b/drivers/gpu/drm/gma500/power.h
index 1969d2ecb328..56d8708bd41c 100644
--- a/drivers/gpu/drm/gma500/power.h
+++ b/drivers/gpu/drm/gma500/power.h
@@ -41,6 +41,9 @@ void gma_power_uninit(struct drm_device *dev);
41 */ 41 */
42int gma_power_suspend(struct device *dev); 42int gma_power_suspend(struct device *dev);
43int gma_power_resume(struct device *dev); 43int gma_power_resume(struct device *dev);
44int gma_power_thaw(struct device *dev);
45int gma_power_freeze(struct device *dev);
46int gma_power_restore(struct device *_dev);
44 47
45/* 48/*
46 * These are the functions the driver should use to wrap all hw access 49 * These are the functions the driver should use to wrap all hw access
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 111e3df9c5de..bddea5807442 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -601,6 +601,9 @@ static void psb_remove(struct pci_dev *pdev)
601static const struct dev_pm_ops psb_pm_ops = { 601static const struct dev_pm_ops psb_pm_ops = {
602 .resume = gma_power_resume, 602 .resume = gma_power_resume,
603 .suspend = gma_power_suspend, 603 .suspend = gma_power_suspend,
604 .thaw = gma_power_thaw,
605 .freeze = gma_power_freeze,
606 .restore = gma_power_restore,
604 .runtime_suspend = psb_runtime_suspend, 607 .runtime_suspend = psb_runtime_suspend,
605 .runtime_resume = psb_runtime_resume, 608 .runtime_resume = psb_runtime_resume,
606 .runtime_idle = psb_runtime_idle, 609 .runtime_idle = psb_runtime_idle,
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index a7fd6c48b793..6053b8abcd12 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -876,7 +876,6 @@ extern const struct psb_ops cdv_chip_ops;
876#define PSB_D_MSVDX (1 << 9) 876#define PSB_D_MSVDX (1 << 9)
877#define PSB_D_TOPAZ (1 << 10) 877#define PSB_D_TOPAZ (1 << 10)
878 878
879extern int drm_psb_no_fb;
880extern int drm_idle_check_interval; 879extern int drm_idle_check_interval;
881 880
882/* 881/*
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
index 9edb1902a096..6e8f42b61ff6 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -50,119 +50,41 @@ struct psb_intel_p2_t {
50 int p2_slow, p2_fast; 50 int p2_slow, p2_fast;
51}; 51};
52 52
53#define INTEL_P2_NUM 2
54
55struct psb_intel_limit_t { 53struct psb_intel_limit_t {
56 struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1; 54 struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
57 struct psb_intel_p2_t p2; 55 struct psb_intel_p2_t p2;
58}; 56};
59 57
60#define I8XX_DOT_MIN 25000 58#define INTEL_LIMIT_I9XX_SDVO_DAC 0
61#define I8XX_DOT_MAX 350000 59#define INTEL_LIMIT_I9XX_LVDS 1
62#define I8XX_VCO_MIN 930000
63#define I8XX_VCO_MAX 1400000
64#define I8XX_N_MIN 3
65#define I8XX_N_MAX 16
66#define I8XX_M_MIN 96
67#define I8XX_M_MAX 140
68#define I8XX_M1_MIN 18
69#define I8XX_M1_MAX 26
70#define I8XX_M2_MIN 6
71#define I8XX_M2_MAX 16
72#define I8XX_P_MIN 4
73#define I8XX_P_MAX 128
74#define I8XX_P1_MIN 2
75#define I8XX_P1_MAX 33
76#define I8XX_P1_LVDS_MIN 1
77#define I8XX_P1_LVDS_MAX 6
78#define I8XX_P2_SLOW 4
79#define I8XX_P2_FAST 2
80#define I8XX_P2_LVDS_SLOW 14
81#define I8XX_P2_LVDS_FAST 14 /* No fast option */
82#define I8XX_P2_SLOW_LIMIT 165000
83
84#define I9XX_DOT_MIN 20000
85#define I9XX_DOT_MAX 400000
86#define I9XX_VCO_MIN 1400000
87#define I9XX_VCO_MAX 2800000
88#define I9XX_N_MIN 1
89#define I9XX_N_MAX 6
90#define I9XX_M_MIN 70
91#define I9XX_M_MAX 120
92#define I9XX_M1_MIN 8
93#define I9XX_M1_MAX 18
94#define I9XX_M2_MIN 3
95#define I9XX_M2_MAX 7
96#define I9XX_P_SDVO_DAC_MIN 5
97#define I9XX_P_SDVO_DAC_MAX 80
98#define I9XX_P_LVDS_MIN 7
99#define I9XX_P_LVDS_MAX 98
100#define I9XX_P1_MIN 1
101#define I9XX_P1_MAX 8
102#define I9XX_P2_SDVO_DAC_SLOW 10
103#define I9XX_P2_SDVO_DAC_FAST 5
104#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000
105#define I9XX_P2_LVDS_SLOW 14
106#define I9XX_P2_LVDS_FAST 7
107#define I9XX_P2_LVDS_SLOW_LIMIT 112000
108
109#define INTEL_LIMIT_I8XX_DVO_DAC 0
110#define INTEL_LIMIT_I8XX_LVDS 1
111#define INTEL_LIMIT_I9XX_SDVO_DAC 2
112#define INTEL_LIMIT_I9XX_LVDS 3
113 60
114static const struct psb_intel_limit_t psb_intel_limits[] = { 61static const struct psb_intel_limit_t psb_intel_limits[] = {
115 { /* INTEL_LIMIT_I8XX_DVO_DAC */
116 .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
117 .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
118 .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
119 .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
120 .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
121 .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
122 .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
123 .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX},
124 .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
125 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST},
126 },
127 { /* INTEL_LIMIT_I8XX_LVDS */
128 .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
129 .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
130 .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
131 .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
132 .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
133 .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
134 .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
135 .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX},
136 .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
137 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST},
138 },
139 { /* INTEL_LIMIT_I9XX_SDVO_DAC */ 62 { /* INTEL_LIMIT_I9XX_SDVO_DAC */
140 .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, 63 .dot = {.min = 20000, .max = 400000},
141 .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, 64 .vco = {.min = 1400000, .max = 2800000},
142 .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, 65 .n = {.min = 1, .max = 6},
143 .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, 66 .m = {.min = 70, .max = 120},
144 .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, 67 .m1 = {.min = 8, .max = 18},
145 .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, 68 .m2 = {.min = 3, .max = 7},
146 .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX}, 69 .p = {.min = 5, .max = 80},
147 .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, 70 .p1 = {.min = 1, .max = 8},
148 .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 71 .p2 = {.dot_limit = 200000,
149 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = 72 .p2_slow = 10, .p2_fast = 5},
150 I9XX_P2_SDVO_DAC_FAST},
151 }, 73 },
152 { /* INTEL_LIMIT_I9XX_LVDS */ 74 { /* INTEL_LIMIT_I9XX_LVDS */
153 .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, 75 .dot = {.min = 20000, .max = 400000},
154 .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, 76 .vco = {.min = 1400000, .max = 2800000},
155 .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, 77 .n = {.min = 1, .max = 6},
156 .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, 78 .m = {.min = 70, .max = 120},
157 .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, 79 .m1 = {.min = 8, .max = 18},
158 .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, 80 .m2 = {.min = 3, .max = 7},
159 .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX}, 81 .p = {.min = 7, .max = 98},
160 .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, 82 .p1 = {.min = 1, .max = 8},
161 /* The single-channel range is 25-112Mhz, and dual-channel 83 /* The single-channel range is 25-112Mhz, and dual-channel
162 * is 80-224Mhz. Prefer single channel as much as possible. 84 * is 80-224Mhz. Prefer single channel as much as possible.
163 */ 85 */
164 .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 86 .p2 = {.dot_limit = 112000,
165 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST}, 87 .p2_slow = 14, .p2_fast = 7},
166 }, 88 },
167}; 89};
168 90
@@ -177,9 +99,7 @@ static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc)
177 return limit; 99 return limit;
178} 100}
179 101
180/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ 102static void psb_intel_clock(int refclk, struct psb_intel_clock_t *clock)
181
182static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
183{ 103{
184 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); 104 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
185 clock->p = clock->p1 * clock->p2; 105 clock->p = clock->p1 * clock->p2;
@@ -187,22 +107,6 @@ static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
187 clock->dot = clock->vco / clock->p; 107 clock->dot = clock->vco / clock->p;
188} 108}
189 109
190/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
191
192static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock)
193{
194 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
195 clock->p = clock->p1 * clock->p2;
196 clock->vco = refclk * clock->m / (clock->n + 2);
197 clock->dot = clock->vco / clock->p;
198}
199
200static void psb_intel_clock(struct drm_device *dev, int refclk,
201 struct psb_intel_clock_t *clock)
202{
203 return i9xx_clock(refclk, clock);
204}
205
206/** 110/**
207 * Returns whether any output on the specified pipe is of the specified type 111 * Returns whether any output on the specified pipe is of the specified type
208 */ 112 */
@@ -308,7 +212,7 @@ static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
308 clock.p1++) { 212 clock.p1++) {
309 int this_err; 213 int this_err;
310 214
311 psb_intel_clock(dev, refclk, &clock); 215 psb_intel_clock(refclk, &clock);
312 216
313 if (!psb_intel_PLL_is_valid 217 if (!psb_intel_PLL_is_valid
314 (crtc, &clock)) 218 (crtc, &clock))
@@ -1068,7 +972,7 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1068 return 0; 972 return 0;
1069} 973}
1070 974
1071void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, 975static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
1072 u16 *green, u16 *blue, uint32_t type, uint32_t size) 976 u16 *green, u16 *blue, uint32_t type, uint32_t size)
1073{ 977{
1074 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 978 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
@@ -1149,9 +1053,9 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev,
1149 if ((dpll & PLL_REF_INPUT_MASK) == 1053 if ((dpll & PLL_REF_INPUT_MASK) ==
1150 PLLB_REF_INPUT_SPREADSPECTRUMIN) { 1054 PLLB_REF_INPUT_SPREADSPECTRUMIN) {
1151 /* XXX: might not be 66MHz */ 1055 /* XXX: might not be 66MHz */
1152 i8xx_clock(66000, &clock); 1056 psb_intel_clock(66000, &clock);
1153 } else 1057 } else
1154 i8xx_clock(48000, &clock); 1058 psb_intel_clock(48000, &clock);
1155 } else { 1059 } else {
1156 if (dpll & PLL_P1_DIVIDE_BY_TWO) 1060 if (dpll & PLL_P1_DIVIDE_BY_TWO)
1157 clock.p1 = 2; 1061 clock.p1 = 2;
@@ -1166,7 +1070,7 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev,
1166 else 1070 else
1167 clock.p2 = 2; 1071 clock.p2 = 2;
1168 1072
1169 i8xx_clock(48000, &clock); 1073 psb_intel_clock(48000, &clock);
1170 } 1074 }
1171 1075
1172 /* XXX: It would be nice to validate the clocks, but we can't reuse 1076 /* XXX: It would be nice to validate the clocks, but we can't reuse
@@ -1225,7 +1129,7 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
1225 return mode; 1129 return mode;
1226} 1130}
1227 1131
1228void psb_intel_crtc_destroy(struct drm_crtc *crtc) 1132static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
1229{ 1133{
1230 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 1134 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1231 struct gtt_range *gt; 1135 struct gtt_range *gt;
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.h b/drivers/gpu/drm/gma500/psb_intel_display.h
index 535b49a5e409..3724b971e91c 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.h
+++ b/drivers/gpu/drm/gma500/psb_intel_display.h
@@ -21,8 +21,5 @@
21#define _INTEL_DISPLAY_H_ 21#define _INTEL_DISPLAY_H_
22 22
23bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type); 23bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
24void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
25 u16 *green, u16 *blue, uint32_t type, uint32_t size);
26void psb_intel_crtc_destroy(struct drm_crtc *crtc);
27 24
28#endif 25#endif
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 90f2d11e686b..4dcae421a58d 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -32,9 +32,6 @@
32/* maximum connectors per crtcs in the mode set */ 32/* maximum connectors per crtcs in the mode set */
33#define INTELFB_CONN_LIMIT 4 33#define INTELFB_CONN_LIMIT 4
34 34
35#define INTEL_I2C_BUS_DVO 1
36#define INTEL_I2C_BUS_SDVO 2
37
38/* Intel Pipe Clone Bit */ 35/* Intel Pipe Clone Bit */
39#define INTEL_HDMIB_CLONE_BIT 1 36#define INTEL_HDMIB_CLONE_BIT 1
40#define INTEL_HDMIC_CLONE_BIT 2 37#define INTEL_HDMIC_CLONE_BIT 2
@@ -68,11 +65,6 @@
68#define INTEL_OUTPUT_DISPLAYPORT 9 65#define INTEL_OUTPUT_DISPLAYPORT 9
69#define INTEL_OUTPUT_EDP 10 66#define INTEL_OUTPUT_EDP 10
70 67
71#define INTEL_DVO_CHIP_NONE 0
72#define INTEL_DVO_CHIP_LVDS 1
73#define INTEL_DVO_CHIP_TMDS 2
74#define INTEL_DVO_CHIP_TVOUT 4
75
76#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) 68#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
77#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) 69#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
78 70
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h
index d914719c4b60..0be30e4d146d 100644
--- a/drivers/gpu/drm/gma500/psb_intel_reg.h
+++ b/drivers/gpu/drm/gma500/psb_intel_reg.h
@@ -493,7 +493,6 @@
493#define PIPEACONF_DISABLE 0 493#define PIPEACONF_DISABLE 0
494#define PIPEACONF_DOUBLE_WIDE (1 << 30) 494#define PIPEACONF_DOUBLE_WIDE (1 << 30)
495#define PIPECONF_ACTIVE (1 << 30) 495#define PIPECONF_ACTIVE (1 << 30)
496#define I965_PIPECONF_ACTIVE (1 << 30)
497#define PIPECONF_DSIPLL_LOCK (1 << 29) 496#define PIPECONF_DSIPLL_LOCK (1 << 29)
498#define PIPEACONF_SINGLE_WIDE 0 497#define PIPEACONF_SINGLE_WIDE 0
499#define PIPEACONF_PIPE_UNLOCKED 0 498#define PIPEACONF_PIPE_UNLOCKED 0
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index a4cc777ab7a6..19e36603b23b 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -134,6 +134,9 @@ struct psb_intel_sdvo {
134 134
135 /* Input timings for adjusted_mode */ 135 /* Input timings for adjusted_mode */
136 struct psb_intel_sdvo_dtd input_dtd; 136 struct psb_intel_sdvo_dtd input_dtd;
137
138 /* Saved SDVO output states */
139 uint32_t saveSDVO; /* Can be SDVOB or SDVOC depending on sdvo_reg */
137}; 140};
138 141
139struct psb_intel_sdvo_connector { 142struct psb_intel_sdvo_connector {
@@ -1830,6 +1833,34 @@ done:
1830#undef CHECK_PROPERTY 1833#undef CHECK_PROPERTY
1831} 1834}
1832 1835
1836static void psb_intel_sdvo_save(struct drm_connector *connector)
1837{
1838 struct drm_device *dev = connector->dev;
1839 struct psb_intel_encoder *psb_intel_encoder =
1840 psb_intel_attached_encoder(connector);
1841 struct psb_intel_sdvo *sdvo =
1842 to_psb_intel_sdvo(&psb_intel_encoder->base);
1843
1844 sdvo->saveSDVO = REG_READ(sdvo->sdvo_reg);
1845}
1846
1847static void psb_intel_sdvo_restore(struct drm_connector *connector)
1848{
1849 struct drm_device *dev = connector->dev;
1850 struct drm_encoder *encoder =
1851 &psb_intel_attached_encoder(connector)->base;
1852 struct psb_intel_sdvo *sdvo = to_psb_intel_sdvo(encoder);
1853 struct drm_crtc *crtc = encoder->crtc;
1854
1855 REG_WRITE(sdvo->sdvo_reg, sdvo->saveSDVO);
1856
1857 /* Force a full mode set on the crtc. We're supposed to have the
1858 mode_config lock already. */
1859 if (connector->status == connector_status_connected)
1860 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
1861 NULL);
1862}
1863
1833static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { 1864static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
1834 .dpms = psb_intel_sdvo_dpms, 1865 .dpms = psb_intel_sdvo_dpms,
1835 .mode_fixup = psb_intel_sdvo_mode_fixup, 1866 .mode_fixup = psb_intel_sdvo_mode_fixup,
@@ -1840,6 +1871,8 @@ static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
1840 1871
1841static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { 1872static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
1842 .dpms = drm_helper_connector_dpms, 1873 .dpms = drm_helper_connector_dpms,
1874 .save = psb_intel_sdvo_save,
1875 .restore = psb_intel_sdvo_restore,
1843 .detect = psb_intel_sdvo_detect, 1876 .detect = psb_intel_sdvo_detect,
1844 .fill_modes = drm_helper_probe_single_connector_modes, 1877 .fill_modes = drm_helper_probe_single_connector_modes,
1845 .set_property = psb_intel_sdvo_set_property, 1878 .set_property = psb_intel_sdvo_set_property,
diff --git a/drivers/gpu/drm/gma500/psb_irq.h b/drivers/gpu/drm/gma500/psb_irq.h
index 603045bee58a..debb7f190c06 100644
--- a/drivers/gpu/drm/gma500/psb_irq.h
+++ b/drivers/gpu/drm/gma500/psb_irq.h
@@ -21,8 +21,8 @@
21 * 21 *
22 **************************************************************************/ 22 **************************************************************************/
23 23
24#ifndef _SYSIRQ_H_ 24#ifndef _PSB_IRQ_H_
25#define _SYSIRQ_H_ 25#define _PSB_IRQ_H_
26 26
27#include <drm/drmP.h> 27#include <drm/drmP.h>
28 28
@@ -44,4 +44,4 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe);
44 44
45int mdfld_enable_te(struct drm_device *dev, int pipe); 45int mdfld_enable_te(struct drm_device *dev, int pipe);
46void mdfld_disable_te(struct drm_device *dev, int pipe); 46void mdfld_disable_te(struct drm_device *dev, int pipe);
47#endif /* _SYSIRQ_H_ */ 47#endif /* _PSB_IRQ_H_ */