hybrid-graphics-linux team mailing list archive
-
hybrid-graphics-linux team
-
Mailing list archive
-
Message #00110
Re: RadeonHD+IntelGMA switchable
On Tue, 13 Jul 2010, Andreas Demmer wrote:
On Tuesday 13 July 2010 20:42:00 you wrote:
BTW, who is doing that bios remapping during card switch? I just dumped
memory with dd from 0xc0000 and it is intel vga bios. Switched to radeon -
but memory dump shows the same intel bios.
Ah, now we're getting closer to the source of the trouble! :)
Pocking around I figured out the bios is suppied uing ATRM ACPI call in
radeon kms driver. I've patched a little radeon & switcheroo to export
bios to switcheroo's debugfs so I have it now. Now need to consideer what
to do next %)
My patches are attached if someone interested.
BTW, Dave, I see some kind of excessive call in attempt to fetch bios:
radeon_bios.c:431:radeon_get_bios
r = radeon_atrm_get_bios(rdev);
if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
if (r == false) {
r = radeon_read_disabled_bios(rdev);
}
Here igp_read_bios_from_vram is called and then radeon_read_disabled_bios,
but radeon_read_disabled_bios is also calling igp_read_bios_from_vram
(line 413)
if (rdev->flags & RADEON_IS_IGP)
return igp_read_bios_from_vram(rdev);
or it is a workaround when IGP flag isn't set?
---
Looking forward to reading yours.
Ruslan N. Marchenko
--- drivers/gpu/drm/radeon/radeon_bios.c.orig 2010-07-14 18:25:08.017712773 +0200
+++ drivers/gpu/drm/radeon/radeon_bios.c 2010-07-14 18:28:14.938954830 +0200
@@ -465,6 +465,7 @@
}
DRM_DEBUG("%sBIOS detected\n", rdev->is_atom_bios ? "ATOM" : "COM");
+ vga_switcheroo_publish_rom(rdev->bios);
return true;
free_bios:
kfree(rdev->bios);
--- drivers/gpu/vga/vga_switcheroo.c.orig 2010-07-14 19:14:42.159588542 +0200
+++ drivers/gpu/vga/vga_switcheroo.c 2010-07-14 19:16:00.517715175 +0200
@@ -48,6 +48,7 @@
struct dentry *debugfs_root;
struct dentry *switch_file;
+ struct dentry *bios_file;
int registered_clients;
struct vga_switcheroo_client clients[VGA_SWITCHEROO_MAX_CLIENTS];
@@ -169,6 +170,26 @@
}
EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
+static DEFINE_MUTEX(bios_mutex);
+char priv_bios[65536];
+void vga_switcheroo_publish_rom(char *rom)
+{
+ mutex_lock(&bios_mutex);
+ memcpy(priv_bios,rom,65536);
+ mutex_unlock(&bios_mutex);
+}
+EXPORT_SYMBOL(vga_switcheroo_publish_rom);
+static ssize_t vga_switcheroo_read_bios(struct file *file,
+ char __user * buffer, size_t count, loff_t * ppos)
+{
+ ssize_t ret;
+ mutex_lock(&bios_mutex);
+ ret = simple_read_from_buffer(buffer, count, ppos, priv_bios, 65536);
+ mutex_unlock(&bios_mutex);
+ return ret;
+}
+
+
static int vga_switcheroo_show(struct seq_file *m, void *v)
{
int i;
@@ -371,6 +392,9 @@
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
+}, vga_switcheroo_dbgfs_rom_fops = {
+ .owner= THIS_MODULE,
+ .read = vga_switcheroo_read_bios,
};
static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
@@ -379,6 +403,10 @@
debugfs_remove(priv->switch_file);
priv->switch_file = NULL;
}
+ if (priv->bios_file) {
+ debugfs_remove(priv->bios_file);
+ priv->bios_file = NULL;
+ }
if (priv->debugfs_root) {
debugfs_remove(priv->debugfs_root);
priv->debugfs_root = NULL;
@@ -403,6 +431,12 @@
printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/switch\n");
goto fail;
}
+ priv->bios_file = debugfs_create_file("bios", 0400,
+ priv->debugfs_root, NULL, &vga_switcheroo_dbgfs_rom_fops);
+ if (!priv->switch_file) {
+ printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/bios\n");
+ goto fail;
+ }
return 0;
fail:
vga_switcheroo_debugfs_fini(priv);
--- include/linux/vga_switcheroo.h.orig 2010-07-14 19:17:20.727802755 +0200
+++ include/linux/vga_switcheroo.h 2010-07-14 19:19:28.587762711 +0200
@@ -40,6 +40,7 @@
int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler);
void vga_switcheroo_unregister_handler(void);
+void vga_switcheroo_publish_rom(char *rom);
int vga_switcheroo_process_delayed_switch(void);
@@ -52,6 +53,7 @@
static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {}
static inline int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) { return 0; }
static inline void vga_switcheroo_unregister_handler(void) {}
+static inline void vga_switcheroo_publish_rom(char *rom) {}
static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
#endif
Follow ups
References