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
This commit is contained in:
Dave Airlie 2013-04-17 15:18:32 +10:00
commit 9f7bc6acf7
19 changed files with 154 additions and 162 deletions

View File

@ -2,10 +2,15 @@ config DRM_GMA500
tristate "Intel GMA5/600 KMS Framebuffer" tristate "Intel GMA5/600 KMS Framebuffer"
depends on DRM && PCI && X86 depends on DRM && PCI && X86
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_TTM select DRM_TTM
# GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
select ACPI_VIDEO if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
select VIDEO_OUTPUT_CONTROL if ACPI
select INPUT if ACPI
help help
Say yes for an experimental 2D KMS framebuffer driver for the Say yes for an experimental 2D KMS framebuffer driver for the
Intel GMA500 ('Poulsbo') and other Intel IMG based graphics Intel GMA500 ('Poulsbo') and other Intel IMG based graphics

View File

@ -276,6 +276,7 @@ void cdv_intel_crt_init(struct drm_device *dev,
goto failed_connector; goto failed_connector;
connector = &psb_intel_connector->base; connector = &psb_intel_connector->base;
connector->polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_init(dev, connector, drm_connector_init(dev, connector,
&cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);

View File

@ -319,6 +319,7 @@ void cdv_hdmi_init(struct drm_device *dev,
goto err_priv; goto err_priv;
connector = &psb_intel_connector->base; connector = &psb_intel_connector->base;
connector->polled = DRM_CONNECTOR_POLL_HPD;
encoder = &psb_intel_encoder->base; encoder = &psb_intel_encoder->base;
drm_connector_init(dev, connector, drm_connector_init(dev, connector,
&cdv_hdmi_connector_funcs, &cdv_hdmi_connector_funcs,

View File

@ -431,7 +431,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
fbdev->psb_fb_helper.fbdev = info; fbdev->psb_fb_helper.fbdev = info;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
strcpy(info->fix.id, "psbfb"); strcpy(info->fix.id, "psbdrmfb");
info->flags = FBINFO_DEFAULT; info->flags = FBINFO_DEFAULT;
if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */ if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */

View File

@ -80,7 +80,8 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
* the GTT. This is protected via the gtt mutex which the caller * the GTT. This is protected via the gtt mutex which the caller
* must hold. * must hold.
*/ */
static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,
int resume)
{ {
u32 __iomem *gtt_slot; u32 __iomem *gtt_slot;
u32 pte; u32 pte;
@ -97,8 +98,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
gtt_slot = psb_gtt_entry(dev, r); gtt_slot = psb_gtt_entry(dev, r);
pages = r->pages; pages = r->pages;
/* Make sure changes are visible to the GPU */ if (!resume) {
set_pages_array_wc(pages, r->npage); /* Make sure changes are visible to the GPU */
set_pages_array_wc(pages, r->npage);
}
/* Write our page entries into the GTT itself */ /* Write our page entries into the GTT itself */
for (i = r->roll; i < r->npage; i++) { for (i = r->roll; i < r->npage; i++) {
@ -269,7 +272,7 @@ int psb_gtt_pin(struct gtt_range *gt)
ret = psb_gtt_attach_pages(gt); ret = psb_gtt_attach_pages(gt);
if (ret < 0) if (ret < 0)
goto out; goto out;
ret = psb_gtt_insert(dev, gt); ret = psb_gtt_insert(dev, gt, 0);
if (ret < 0) { if (ret < 0) {
psb_gtt_detach_pages(gt); psb_gtt_detach_pages(gt);
goto out; goto out;
@ -421,9 +424,11 @@ int psb_gtt_init(struct drm_device *dev, int resume)
int ret = 0; int ret = 0;
uint32_t pte; uint32_t pte;
mutex_init(&dev_priv->gtt_mutex); if (!resume) {
mutex_init(&dev_priv->gtt_mutex);
psb_gtt_alloc(dev);
}
psb_gtt_alloc(dev);
pg = &dev_priv->gtt; pg = &dev_priv->gtt;
/* Enable the GTT */ /* Enable the GTT */
@ -505,7 +510,8 @@ int psb_gtt_init(struct drm_device *dev, int resume)
/* /*
* Map the GTT and the stolen memory area * Map the GTT and the stolen memory area
*/ */
dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, if (!resume)
dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
gtt_pages << PAGE_SHIFT); gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) { if (!dev_priv->gtt_map) {
dev_err(dev->dev, "Failure to map gtt.\n"); dev_err(dev->dev, "Failure to map gtt.\n");
@ -513,7 +519,9 @@ int psb_gtt_init(struct drm_device *dev, int resume)
goto out_err; goto out_err;
} }
dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); if (!resume)
dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base,
stolen_size);
if (!dev_priv->vram_addr) { if (!dev_priv->vram_addr) {
dev_err(dev->dev, "Failure to map stolen base.\n"); dev_err(dev->dev, "Failure to map stolen base.\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -549,3 +557,31 @@ out_err:
psb_gtt_takedown(dev); psb_gtt_takedown(dev);
return ret; return ret;
} }
int psb_gtt_restore(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
struct resource *r = dev_priv->gtt_mem->child;
struct gtt_range *range;
unsigned int restored = 0, total = 0, size = 0;
/* On resume, the gtt_mutex is already initialized */
mutex_lock(&dev_priv->gtt_mutex);
psb_gtt_init(dev, 1);
while (r != NULL) {
range = container_of(r, struct gtt_range, resource);
if (range->pages) {
psb_gtt_insert(dev, range, 1);
size += range->resource.end - range->resource.start;
restored++;
}
r = r->sibling;
total++;
}
mutex_unlock(&dev_priv->gtt_mutex);
DRM_DEBUG_DRIVER("Restored %u of %u gtt ranges (%u KB)", restored,
total, (size / 1024));
return 0;
}

View File

@ -60,5 +60,5 @@ extern int psb_gtt_pin(struct gtt_range *gt);
extern void psb_gtt_unpin(struct gtt_range *gt); extern void psb_gtt_unpin(struct gtt_range *gt);
extern void psb_gtt_roll(struct drm_device *dev, extern void psb_gtt_roll(struct drm_device *dev,
struct gtt_range *gt, int roll); struct gtt_range *gt, int roll);
extern int psb_gtt_restore(struct drm_device *dev);
#endif #endif

View File

@ -218,12 +218,11 @@ static void parse_backlight_data(struct drm_psb_private *dev_priv,
bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT); bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type; vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL); lvds_bl = kmemdup(vbt_lvds_bl, sizeof(*vbt_lvds_bl), GFP_KERNEL);
if (!lvds_bl) { if (!lvds_bl) {
dev_err(dev_priv->dev->dev, "out of memory for backlight data\n"); dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
return; return;
} }
memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
dev_priv->lvds_bl = lvds_bl; dev_priv->lvds_bl = lvds_bl;
} }

View File

@ -19,8 +19,8 @@
* *
*/ */
#ifndef _I830_BIOS_H_ #ifndef _INTEL_BIOS_H_
#define _I830_BIOS_H_ #define _INTEL_BIOS_H_
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
@ -618,4 +618,4 @@ extern void psb_intel_destroy_bios(struct drm_device *dev);
#define PORT_IDPC 8 #define PORT_IDPC 8
#define PORT_IDPD 9 #define PORT_IDPD 9
#endif /* _I830_BIOS_H_ */ #endif /* _INTEL_BIOS_H_ */

View File

@ -92,8 +92,8 @@ void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe)
{ {
struct mdfld_dsi_pkg_sender *sender = struct mdfld_dsi_pkg_sender *sender =
mdfld_dsi_get_pkg_sender(dsi_config); mdfld_dsi_get_pkg_sender(dsi_config);
struct drm_device *dev = sender->dev; struct drm_device *dev;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv;
u32 gen_ctrl_val; u32 gen_ctrl_val;
if (!sender) { if (!sender) {
@ -101,6 +101,9 @@ void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe)
return; return;
} }
dev = sender->dev;
dev_priv = dev->dev_private;
/* Set default display backlight value to 85% (0xd8)*/ /* Set default display backlight value to 85% (0xd8)*/
mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1, mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1,
true); true);

View File

@ -110,6 +110,8 @@ static void gma_resume_display(struct pci_dev *pdev)
PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
pci_write_config_word(pdev, PSB_GMCH_CTRL, pci_write_config_word(pdev, PSB_GMCH_CTRL,
dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
psb_gtt_restore(dev); /* Rebuild our GTT mappings */
dev_priv->ops->restore_regs(dev); dev_priv->ops->restore_regs(dev);
} }
@ -313,3 +315,18 @@ int psb_runtime_idle(struct device *dev)
else else
return 1; return 1;
} }
int gma_power_thaw(struct device *_dev)
{
return gma_power_resume(_dev);
}
int gma_power_freeze(struct device *_dev)
{
return gma_power_suspend(_dev);
}
int gma_power_restore(struct device *_dev)
{
return gma_power_resume(_dev);
}

View File

@ -41,6 +41,9 @@ void gma_power_uninit(struct drm_device *dev);
*/ */
int gma_power_suspend(struct device *dev); int gma_power_suspend(struct device *dev);
int gma_power_resume(struct device *dev); int gma_power_resume(struct device *dev);
int gma_power_thaw(struct device *dev);
int gma_power_freeze(struct device *dev);
int gma_power_restore(struct device *_dev);
/* /*
* These are the functions the driver should use to wrap all hw access * These are the functions the driver should use to wrap all hw access

View File

@ -601,6 +601,9 @@ static void psb_remove(struct pci_dev *pdev)
static const struct dev_pm_ops psb_pm_ops = { static const struct dev_pm_ops psb_pm_ops = {
.resume = gma_power_resume, .resume = gma_power_resume,
.suspend = gma_power_suspend, .suspend = gma_power_suspend,
.thaw = gma_power_thaw,
.freeze = gma_power_freeze,
.restore = gma_power_restore,
.runtime_suspend = psb_runtime_suspend, .runtime_suspend = psb_runtime_suspend,
.runtime_resume = psb_runtime_resume, .runtime_resume = psb_runtime_resume,
.runtime_idle = psb_runtime_idle, .runtime_idle = psb_runtime_idle,

View File

@ -876,7 +876,6 @@ extern const struct psb_ops cdv_chip_ops;
#define PSB_D_MSVDX (1 << 9) #define PSB_D_MSVDX (1 << 9)
#define PSB_D_TOPAZ (1 << 10) #define PSB_D_TOPAZ (1 << 10)
extern int drm_psb_no_fb;
extern int drm_idle_check_interval; extern int drm_idle_check_interval;
/* /*

View File

@ -50,119 +50,41 @@ struct psb_intel_p2_t {
int p2_slow, p2_fast; int p2_slow, p2_fast;
}; };
#define INTEL_P2_NUM 2
struct psb_intel_limit_t { struct psb_intel_limit_t {
struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1; struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
struct psb_intel_p2_t p2; struct psb_intel_p2_t p2;
}; };
#define I8XX_DOT_MIN 25000 #define INTEL_LIMIT_I9XX_SDVO_DAC 0
#define I8XX_DOT_MAX 350000 #define INTEL_LIMIT_I9XX_LVDS 1
#define I8XX_VCO_MIN 930000
#define I8XX_VCO_MAX 1400000
#define I8XX_N_MIN 3
#define I8XX_N_MAX 16
#define I8XX_M_MIN 96
#define I8XX_M_MAX 140
#define I8XX_M1_MIN 18
#define I8XX_M1_MAX 26
#define I8XX_M2_MIN 6
#define I8XX_M2_MAX 16
#define I8XX_P_MIN 4
#define I8XX_P_MAX 128
#define I8XX_P1_MIN 2
#define I8XX_P1_MAX 33
#define I8XX_P1_LVDS_MIN 1
#define I8XX_P1_LVDS_MAX 6
#define I8XX_P2_SLOW 4
#define I8XX_P2_FAST 2
#define I8XX_P2_LVDS_SLOW 14
#define I8XX_P2_LVDS_FAST 14 /* No fast option */
#define I8XX_P2_SLOW_LIMIT 165000
#define I9XX_DOT_MIN 20000
#define I9XX_DOT_MAX 400000
#define I9XX_VCO_MIN 1400000
#define I9XX_VCO_MAX 2800000
#define I9XX_N_MIN 1
#define I9XX_N_MAX 6
#define I9XX_M_MIN 70
#define I9XX_M_MAX 120
#define I9XX_M1_MIN 8
#define I9XX_M1_MAX 18
#define I9XX_M2_MIN 3
#define I9XX_M2_MAX 7
#define I9XX_P_SDVO_DAC_MIN 5
#define I9XX_P_SDVO_DAC_MAX 80
#define I9XX_P_LVDS_MIN 7
#define I9XX_P_LVDS_MAX 98
#define I9XX_P1_MIN 1
#define I9XX_P1_MAX 8
#define I9XX_P2_SDVO_DAC_SLOW 10
#define I9XX_P2_SDVO_DAC_FAST 5
#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000
#define I9XX_P2_LVDS_SLOW 14
#define I9XX_P2_LVDS_FAST 7
#define I9XX_P2_LVDS_SLOW_LIMIT 112000
#define INTEL_LIMIT_I8XX_DVO_DAC 0
#define INTEL_LIMIT_I8XX_LVDS 1
#define INTEL_LIMIT_I9XX_SDVO_DAC 2
#define INTEL_LIMIT_I9XX_LVDS 3
static const struct psb_intel_limit_t psb_intel_limits[] = { static const struct psb_intel_limit_t psb_intel_limits[] = {
{ /* INTEL_LIMIT_I8XX_DVO_DAC */
.dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
.vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
.n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
.m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
.m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
.m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
.p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
.p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX},
.p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST},
},
{ /* INTEL_LIMIT_I8XX_LVDS */
.dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
.vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
.n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
.m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
.m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
.m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
.p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
.p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX},
.p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST},
},
{ /* INTEL_LIMIT_I9XX_SDVO_DAC */ { /* INTEL_LIMIT_I9XX_SDVO_DAC */
.dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, .dot = {.min = 20000, .max = 400000},
.vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, .vco = {.min = 1400000, .max = 2800000},
.n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, .n = {.min = 1, .max = 6},
.m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, .m = {.min = 70, .max = 120},
.m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, .m1 = {.min = 8, .max = 18},
.m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, .m2 = {.min = 3, .max = 7},
.p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX}, .p = {.min = 5, .max = 80},
.p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, .p1 = {.min = 1, .max = 8},
.p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2 = {.dot_limit = 200000,
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = .p2_slow = 10, .p2_fast = 5},
I9XX_P2_SDVO_DAC_FAST},
}, },
{ /* INTEL_LIMIT_I9XX_LVDS */ { /* INTEL_LIMIT_I9XX_LVDS */
.dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, .dot = {.min = 20000, .max = 400000},
.vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, .vco = {.min = 1400000, .max = 2800000},
.n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, .n = {.min = 1, .max = 6},
.m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, .m = {.min = 70, .max = 120},
.m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, .m1 = {.min = 8, .max = 18},
.m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, .m2 = {.min = 3, .max = 7},
.p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX}, .p = {.min = 7, .max = 98},
.p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, .p1 = {.min = 1, .max = 8},
/* The single-channel range is 25-112Mhz, and dual-channel /* The single-channel range is 25-112Mhz, and dual-channel
* is 80-224Mhz. Prefer single channel as much as possible. * is 80-224Mhz. Prefer single channel as much as possible.
*/ */
.p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, .p2 = {.dot_limit = 112000,
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST}, .p2_slow = 14, .p2_fast = 7},
}, },
}; };
@ -177,9 +99,7 @@ static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc)
return limit; return limit;
} }
/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ static void psb_intel_clock(int refclk, struct psb_intel_clock_t *clock)
static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
{ {
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
clock->p = clock->p1 * clock->p2; clock->p = clock->p1 * clock->p2;
@ -187,22 +107,6 @@ static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
clock->dot = clock->vco / clock->p; clock->dot = clock->vco / clock->p;
} }
/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock)
{
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
clock->p = clock->p1 * clock->p2;
clock->vco = refclk * clock->m / (clock->n + 2);
clock->dot = clock->vco / clock->p;
}
static void psb_intel_clock(struct drm_device *dev, int refclk,
struct psb_intel_clock_t *clock)
{
return i9xx_clock(refclk, clock);
}
/** /**
* Returns whether any output on the specified pipe is of the specified type * Returns whether any output on the specified pipe is of the specified type
*/ */
@ -308,7 +212,7 @@ static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
clock.p1++) { clock.p1++) {
int this_err; int this_err;
psb_intel_clock(dev, refclk, &clock); psb_intel_clock(refclk, &clock);
if (!psb_intel_PLL_is_valid if (!psb_intel_PLL_is_valid
(crtc, &clock)) (crtc, &clock))
@ -1068,7 +972,7 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
return 0; return 0;
} }
void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, uint32_t type, uint32_t size) u16 *green, u16 *blue, uint32_t type, uint32_t size)
{ {
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 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,
if ((dpll & PLL_REF_INPUT_MASK) == if ((dpll & PLL_REF_INPUT_MASK) ==
PLLB_REF_INPUT_SPREADSPECTRUMIN) { PLLB_REF_INPUT_SPREADSPECTRUMIN) {
/* XXX: might not be 66MHz */ /* XXX: might not be 66MHz */
i8xx_clock(66000, &clock); psb_intel_clock(66000, &clock);
} else } else
i8xx_clock(48000, &clock); psb_intel_clock(48000, &clock);
} else { } else {
if (dpll & PLL_P1_DIVIDE_BY_TWO) if (dpll & PLL_P1_DIVIDE_BY_TWO)
clock.p1 = 2; clock.p1 = 2;
@ -1166,7 +1070,7 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev,
else else
clock.p2 = 2; clock.p2 = 2;
i8xx_clock(48000, &clock); psb_intel_clock(48000, &clock);
} }
/* XXX: It would be nice to validate the clocks, but we can't reuse /* 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,
return mode; return mode;
} }
void psb_intel_crtc_destroy(struct drm_crtc *crtc) static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
{ {
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
struct gtt_range *gt; struct gtt_range *gt;

View File

@ -21,8 +21,5 @@
#define _INTEL_DISPLAY_H_ #define _INTEL_DISPLAY_H_
bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type); bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, uint32_t type, uint32_t size);
void psb_intel_crtc_destroy(struct drm_crtc *crtc);
#endif #endif

View File

@ -32,9 +32,6 @@
/* maximum connectors per crtcs in the mode set */ /* maximum connectors per crtcs in the mode set */
#define INTELFB_CONN_LIMIT 4 #define INTELFB_CONN_LIMIT 4
#define INTEL_I2C_BUS_DVO 1
#define INTEL_I2C_BUS_SDVO 2
/* Intel Pipe Clone Bit */ /* Intel Pipe Clone Bit */
#define INTEL_HDMIB_CLONE_BIT 1 #define INTEL_HDMIB_CLONE_BIT 1
#define INTEL_HDMIC_CLONE_BIT 2 #define INTEL_HDMIC_CLONE_BIT 2
@ -68,11 +65,6 @@
#define INTEL_OUTPUT_DISPLAYPORT 9 #define INTEL_OUTPUT_DISPLAYPORT 9
#define INTEL_OUTPUT_EDP 10 #define INTEL_OUTPUT_EDP 10
#define INTEL_DVO_CHIP_NONE 0
#define INTEL_DVO_CHIP_LVDS 1
#define INTEL_DVO_CHIP_TMDS 2
#define INTEL_DVO_CHIP_TVOUT 4
#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)

View File

@ -493,7 +493,6 @@
#define PIPEACONF_DISABLE 0 #define PIPEACONF_DISABLE 0
#define PIPEACONF_DOUBLE_WIDE (1 << 30) #define PIPEACONF_DOUBLE_WIDE (1 << 30)
#define PIPECONF_ACTIVE (1 << 30) #define PIPECONF_ACTIVE (1 << 30)
#define I965_PIPECONF_ACTIVE (1 << 30)
#define PIPECONF_DSIPLL_LOCK (1 << 29) #define PIPECONF_DSIPLL_LOCK (1 << 29)
#define PIPEACONF_SINGLE_WIDE 0 #define PIPEACONF_SINGLE_WIDE 0
#define PIPEACONF_PIPE_UNLOCKED 0 #define PIPEACONF_PIPE_UNLOCKED 0

View File

@ -134,6 +134,9 @@ struct psb_intel_sdvo {
/* Input timings for adjusted_mode */ /* Input timings for adjusted_mode */
struct psb_intel_sdvo_dtd input_dtd; struct psb_intel_sdvo_dtd input_dtd;
/* Saved SDVO output states */
uint32_t saveSDVO; /* Can be SDVOB or SDVOC depending on sdvo_reg */
}; };
struct psb_intel_sdvo_connector { struct psb_intel_sdvo_connector {
@ -1830,6 +1833,34 @@ done:
#undef CHECK_PROPERTY #undef CHECK_PROPERTY
} }
static void psb_intel_sdvo_save(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct psb_intel_encoder *psb_intel_encoder =
psb_intel_attached_encoder(connector);
struct psb_intel_sdvo *sdvo =
to_psb_intel_sdvo(&psb_intel_encoder->base);
sdvo->saveSDVO = REG_READ(sdvo->sdvo_reg);
}
static void psb_intel_sdvo_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_encoder *encoder =
&psb_intel_attached_encoder(connector)->base;
struct psb_intel_sdvo *sdvo = to_psb_intel_sdvo(encoder);
struct drm_crtc *crtc = encoder->crtc;
REG_WRITE(sdvo->sdvo_reg, sdvo->saveSDVO);
/* Force a full mode set on the crtc. We're supposed to have the
mode_config lock already. */
if (connector->status == connector_status_connected)
drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
NULL);
}
static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
.dpms = psb_intel_sdvo_dpms, .dpms = psb_intel_sdvo_dpms,
.mode_fixup = psb_intel_sdvo_mode_fixup, .mode_fixup = psb_intel_sdvo_mode_fixup,
@ -1840,6 +1871,8 @@ static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.save = psb_intel_sdvo_save,
.restore = psb_intel_sdvo_restore,
.detect = psb_intel_sdvo_detect, .detect = psb_intel_sdvo_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = psb_intel_sdvo_set_property, .set_property = psb_intel_sdvo_set_property,

View File

@ -21,8 +21,8 @@
* *
**************************************************************************/ **************************************************************************/
#ifndef _SYSIRQ_H_ #ifndef _PSB_IRQ_H_
#define _SYSIRQ_H_ #define _PSB_IRQ_H_
#include <drm/drmP.h> #include <drm/drmP.h>
@ -44,4 +44,4 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe);
int mdfld_enable_te(struct drm_device *dev, int pipe); int mdfld_enable_te(struct drm_device *dev, int pipe);
void mdfld_disable_te(struct drm_device *dev, int pipe); void mdfld_disable_te(struct drm_device *dev, int pipe);
#endif /* _SYSIRQ_H_ */ #endif /* _PSB_IRQ_H_ */