mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-27 11:55:53 +00:00
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:
commit
9f7bc6acf7
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_ */
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user