Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 199691
b: refs/heads/master
c: 36d1701
h: refs/heads/master
i:
  199689: c52a9e6
  199687: 8bd28db
v: v3
  • Loading branch information
Dave Airlie committed Jun 1, 2010
1 parent fedffcf commit 3a328f5
Show file tree
Hide file tree
Showing 36 changed files with 660 additions and 215 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8b281db596744a15b2abbfdbf655796c64e172ca
refs/heads/master: 36d1701c502d4f46386e1000ad58d9497a11688d
28 changes: 18 additions & 10 deletions trunk/drivers/char/agp/amd64-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
{
u32 httfea,baseaddr,enuscr;
struct pci_dev *dev1;
int i;
int i, ret;
unsigned size = amd64_fetch_size();

dev_info(&pdev->dev, "setting up ULi AGP\n");
Expand All @@ -400,15 +400,18 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)

if (i == ARRAY_SIZE(uli_sizes)) {
dev_info(&pdev->dev, "no ULi size found for %d\n", size);
return -ENODEV;
ret = -ENODEV;
goto put;
}

/* shadow x86-64 registers into ULi registers */
pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &httfea);

/* if x86-64 aperture base is beyond 4G, exit here */
if ((httfea & 0x7fff) >> (32 - 25))
return -ENODEV;
if ((httfea & 0x7fff) >> (32 - 25)) {
ret = -ENODEV;
goto put;
}

httfea = (httfea& 0x7fff) << 25;

Expand All @@ -420,9 +423,10 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
enuscr= httfea+ (size * 1024 * 1024) - 1;
pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea);
pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr);

ret = 0;
put:
pci_dev_put(dev1);
return 0;
return ret;
}


Expand All @@ -441,7 +445,7 @@ static int nforce3_agp_init(struct pci_dev *pdev)
{
u32 tmp, apbase, apbar, aplimit;
struct pci_dev *dev1;
int i;
int i, ret;
unsigned size = amd64_fetch_size();

dev_info(&pdev->dev, "setting up Nforce3 AGP\n");
Expand All @@ -458,7 +462,8 @@ static int nforce3_agp_init(struct pci_dev *pdev)

if (i == ARRAY_SIZE(nforce3_sizes)) {
dev_info(&pdev->dev, "no NForce3 size found for %d\n", size);
return -ENODEV;
ret = -ENODEV;
goto put;
}

pci_read_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, &tmp);
Expand All @@ -472,7 +477,8 @@ static int nforce3_agp_init(struct pci_dev *pdev)
/* if x86-64 aperture base is beyond 4G, exit here */
if ( (apbase & 0x7fff) >> (32 - 25) ) {
dev_info(&pdev->dev, "aperture base > 4G\n");
return -ENODEV;
ret = -ENODEV;
goto put;
}

apbase = (apbase & 0x7fff) << 25;
Expand All @@ -488,9 +494,11 @@ static int nforce3_agp_init(struct pci_dev *pdev)
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase);
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit);

ret = 0;
put:
pci_dev_put(dev1);

return 0;
return ret;
}

static int __devinit agp_amd64_probe(struct pci_dev *pdev,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ config DRM_RADEON
select FW_LOADER
select DRM_KMS_HELPER
select DRM_TTM
select POWER_SUPPLY
help
Choose this option if you have an ATI Radeon graphics card. There
are both PCI and AGP versions. You don't need to choose this to
Expand Down
28 changes: 22 additions & 6 deletions trunk/drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,31 +860,47 @@ static void output_poll_execute(struct slow_work *work)
}
}

void drm_kms_helper_poll_init(struct drm_device *dev)
void drm_kms_helper_poll_disable(struct drm_device *dev)
{
if (!dev->mode_config.poll_enabled)
return;
delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
}
EXPORT_SYMBOL(drm_kms_helper_poll_disable);

void drm_kms_helper_poll_enable(struct drm_device *dev)
{
struct drm_connector *connector;
bool poll = false;
struct drm_connector *connector;
int ret;

list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->polled)
poll = true;
}
slow_work_register_user(THIS_MODULE);
delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
&output_poll_ops);

if (poll) {
ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD);
if (ret)
DRM_ERROR("delayed enqueue failed %d\n", ret);
}
}
EXPORT_SYMBOL(drm_kms_helper_poll_enable);

void drm_kms_helper_poll_init(struct drm_device *dev)
{
slow_work_register_user(THIS_MODULE);
delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
&output_poll_ops);
dev->mode_config.poll_enabled = true;

drm_kms_helper_poll_enable(dev);
}
EXPORT_SYMBOL(drm_kms_helper_poll_init);

void drm_kms_helper_poll_fini(struct drm_device *dev)
{
delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
drm_kms_helper_poll_disable(dev);
slow_work_unregister_user(THIS_MODULE);
}
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
Expand Down
7 changes: 5 additions & 2 deletions trunk/drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ drm_edid_block_valid(u8 *raw_edid)
csum += raw_edid[i];
if (csum) {
DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
goto bad;

/* allow CEA to slide through, switches mangle this */
if (raw_edid[0] != 0x02)
goto bad;
}

/* per-block-type checks */
Expand Down Expand Up @@ -587,7 +590,7 @@ static struct drm_display_mode drm_dmt_modes[] = {
1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
/* 1600x1200@75Hz */
{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 2025000, 1600, 1664,
{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
/* 1600x1200@85Hz */
Expand Down
4 changes: 3 additions & 1 deletion trunk/drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1399,12 +1399,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
struct drm_device *dev = pci_get_drvdata(pdev);
pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
if (state == VGA_SWITCHEROO_ON) {
printk(KERN_INFO "i915: switched off\n");
printk(KERN_INFO "i915: switched on\n");
/* i915 resume handler doesn't set to D0 */
pci_set_power_state(dev->pdev, PCI_D0);
i915_resume(dev);
drm_kms_helper_poll_enable(dev);
} else {
printk(KERN_ERR "i915: switched off\n");
drm_kms_helper_poll_disable(dev);
i915_suspend(dev, pmm);
}
}
Expand Down
71 changes: 63 additions & 8 deletions trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
static struct nouveau_dsm_priv {
bool dsm_detected;
acpi_handle dhandle;
acpi_handle dsm_handle;
acpi_handle rom_handle;
} nouveau_dsm_priv;

static const char nouveau_dsm_muid[] = {
Expand Down Expand Up @@ -107,9 +107,9 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
{
if (id == VGA_SWITCHEROO_IGD)
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_STAMINA);
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
else
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_SPEED);
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED);
}

static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
Expand All @@ -118,7 +118,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
if (id == VGA_SWITCHEROO_IGD)
return 0;

return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dsm_handle, state);
return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
}

static int nouveau_dsm_init(void)
Expand Down Expand Up @@ -151,18 +151,18 @@ static bool nouveau_dsm_pci_probe(struct pci_dev *pdev)
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
return false;

status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle);
if (ACPI_FAILURE(status)) {
return false;
}

ret= nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED,
NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
if (ret < 0)
return false;

nouveau_dsm_priv.dhandle = dhandle;
nouveau_dsm_priv.dsm_handle = nvidia_handle;
return true;
}

Expand All @@ -173,14 +173,15 @@ static bool nouveau_dsm_detect(void)
struct pci_dev *pdev = NULL;
int has_dsm = 0;
int vga_count = 0;

while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
vga_count++;

has_dsm |= (nouveau_dsm_pci_probe(pdev) == true);
}

if (vga_count == 2 && has_dsm) {
acpi_get_name(nouveau_dsm_priv.dsm_handle, ACPI_FULL_PATHNAME, &buffer);
acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
acpi_method_name);
nouveau_dsm_priv.dsm_detected = true;
Expand All @@ -204,3 +205,57 @@ void nouveau_unregister_dsm_handler(void)
{
vga_switcheroo_unregister_handler();
}

/* retrieve the ROM in 4k blocks */
static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios,
int offset, int len)
{
acpi_status status;
union acpi_object rom_arg_elements[2], *obj;
struct acpi_object_list rom_arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};

rom_arg.count = 2;
rom_arg.pointer = &rom_arg_elements[0];

rom_arg_elements[0].type = ACPI_TYPE_INTEGER;
rom_arg_elements[0].integer.value = offset;

rom_arg_elements[1].type = ACPI_TYPE_INTEGER;
rom_arg_elements[1].integer.value = len;

status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer);
if (ACPI_FAILURE(status)) {
printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status));
return -ENODEV;
}
obj = (union acpi_object *)buffer.pointer;
memcpy(bios+offset, obj->buffer.pointer, len);
kfree(buffer.pointer);
return len;
}

bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
{
acpi_status status;
acpi_handle dhandle, rom_handle;

if (!nouveau_dsm_priv.dsm_detected)
return false;

dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
return false;

status = acpi_get_handle(dhandle, "_ROM", &rom_handle);
if (ACPI_FAILURE(status))
return false;

nouveau_dsm_priv.rom_handle = rom_handle;
return true;
}

int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
{
return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
}
20 changes: 20 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,25 @@ static void load_vbios_pci(struct drm_device *dev, uint8_t *data)
pci_disable_rom(dev->pdev);
}

static void load_vbios_acpi(struct drm_device *dev, uint8_t *data)
{
int i;
int ret;
int size = 64 * 1024;

if (!nouveau_acpi_rom_supported(dev->pdev))
return;

for (i = 0; i < (size / ROM_BIOS_PAGE); i++) {
ret = nouveau_acpi_get_bios_chunk(data,
(i * ROM_BIOS_PAGE),
ROM_BIOS_PAGE);
if (ret <= 0)
break;
}
return;
}

struct methods {
const char desc[8];
void (*loadbios)(struct drm_device *, uint8_t *);
Expand All @@ -191,6 +210,7 @@ static struct methods nv04_methods[] = {
};

static struct methods nv50_methods[] = {
{ "ACPI", load_vbios_acpi, true },
{ "PRAMIN", load_vbios_pramin, true },
{ "PROM", load_vbios_prom, false },
{ "PCIROM", load_vbios_pci, true },
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/gpu/drm/nouveau/nouveau_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ nouveau_connector_detect(struct drm_connector *connector)
if (nv_encoder && nv_connector->native_mode) {
unsigned status = connector_status_connected;

#ifdef CONFIG_ACPI
#if defined(CONFIG_ACPI_BUTTON) || \
(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
if (!nouveau_ignorelid && !acpi_lid_open())
status = connector_status_unknown;
#endif
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -851,12 +851,17 @@ extern int nouveau_dma_init(struct nouveau_channel *);
extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);

/* nouveau_acpi.c */
#define ROM_BIOS_PAGE 4096
#if defined(CONFIG_ACPI)
void nouveau_register_dsm_handler(void);
void nouveau_unregister_dsm_handler(void);
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
#else
static inline void nouveau_register_dsm_handler(void) {}
static inline void nouveau_unregister_dsm_handler(void) {}
static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
#endif

/* nouveau_backlight.c */
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,15 @@ nouveau_card_init_channel(struct drm_device *dev)
static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
enum vga_switcheroo_state state)
{
struct drm_device *dev = pci_get_drvdata(pdev);
pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
if (state == VGA_SWITCHEROO_ON) {
printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
nouveau_pci_resume(pdev);
drm_kms_helper_poll_enable(dev);
} else {
printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
drm_kms_helper_poll_disable(dev);
nouveau_pci_suspend(pdev, pmm);
}
}
Expand Down
Loading

0 comments on commit 3a328f5

Please sign in to comment.